我们可以防止Service Fabric中ReliableQueue的死锁和超时吗?

时间:2016-06-02 06:57:09

标签: azure-service-fabric

我们在Service Fabric中有一个有状态的服务,包括RunAsync方法和几个服务调用。

一个服务调用允许在ReliableQueue

中排队
using(ITransaction tx = StateManager.CreateTransaction())
{
  await queue.EnqueueAsync(tx, message);
  queueLength = await queue.GetCountAsync(tx);
  await tx.CommitAsync();
}

另一方面,RunAsync尝试出列事件:

using(ITransaction tx = StateManager.CreateTransaction())
{
  await queue.TryDequeueAsync(tx);
  queueLength = await queue.GetCountAsync(tx);
  await tx.CommitAsync();
}

GetCountAsync似乎会导致死锁,因为这两个事务会相互阻塞。如果我们切换顺序会有所帮助:首先计算,然后是出队/入队?

2 个答案:

答案 0 :(得分:1)

在两个不同的地方进行两次交易不应该导致死锁,因为它们就像互斥锁一样。导致他们的是在交易中创建交易。

也许那就是发生了什么?我最近养成了创建交易事务的命名函数的习惯,即DoSomethingTransactionalAsync,如果它是私人助手,我通常会创建两个版本,其中一个采用tx,一个采用tx创建。

例如:

AddToProcessingQueueAsync(ITransaction tx, int num)AddToProcessingQueueTransactionalAsync(int num)

答案 1 :(得分:1)

这可能是由于ReliableQueue今天是严格的FIFO并且一次只允许一个读写器。您可能没有看到死锁,您看到超时(如果不是这样,请纠正我)。除了:

之外,没有真正的方法可以防止超时
  • 确保交易时间不长 - 超过您的需要,并且您阻止了队列中的其他工作。
  • 增加默认事务超时(默认值为4秒,您可以传入不同的值)

重新排序事情不应该导致任何变化。