我们能否防止 Service Fabric 中 ReliableQueue 的死锁和超时?



我们在 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 似乎会导致死锁,因为两个事务相互阻塞。如果我们切换顺序会有帮助吗:所以首先计数,然后取消排队/排队?

这可能是因为今天的ReliableQueue是严格的FIFO,一次只允许一个读取器或写入器。您可能没有看到死锁,而是看到超时(如果不是这种情况,请纠正我)。除了以下方面,没有真正的方法可以防止超时:

  • 确保事务的生存期不长 - 任何超过您需要的时间,并且您正在阻止队列上的其他工作。
  • 增加默认事务超时(默认值为 4 秒,可以传入其他值)

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

在两个不同的地方有两个事务不应该导致死锁,因为它们的行为就像互斥锁一样。但是,导致它们的是在事务中创建事务。

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

例如:

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

最新更新