服务结构中IReliableQueue的并行出列

时间:2017-10-14 00:22:04

标签: azure-service-fabric

我有下面的代码,由两个任务执行,我正在重现两个交易正在进行的行为,并试图从可靠的队列中取出一个项目。

using (var tx = stateManager.CreateTransaction())
{
    LogInfo("{0} Dequeueing at {1}", taskName, DateTime.Now.ToString("hh.mm.ss.ffffff")));
    ConditionalValue<int> result1 = await items.TryDequeueAsync(tx);
    LogInfo("{0} Dequeued at {1}", taskName, DateTime.Now.ToString("hh.mm.ss.ffffff")));      

    if (task == "Task1")
    {        
        await Task.Delay(4000);
    }
    else if (task == "Task2")
    {
        // Do nothing
    }

    await tx.CommitAsync();
}

我首先触发Task1,然后在1秒后触发消防Task2。 Task1出列并等待4秒钟。在等待时,Task2开始事务并尝试出列。但是,它会被阻塞,直到Task1事务完成。

但文档说如下:

Transaction is the unit of concurrency: Users can have multiple transactions 
in-flight at any given point of time but for a given transaction each API 
must be called one at a time. So all Reliable Collection APIs that take in a 
transaction and return a Task, must be awaited one at a time

在我的情况下,我在不同时间为两个任务调用dequeue但仍被阻止。我的理解是否正确?或者我在代码中做错了什么?

1 个答案:

答案 0 :(得分:1)

IReliableQueue有一些不同的行为,因为它是严格的先进先出(FIFO)。例如,如果您中止Task1的事务,该项将保留在队列的顶部。如果他们允许Task2成功,那么队列顺序将不会被保留,您将成功从队列而不是第一个项目中删除第二个项目。由于这种FIFO行为,IReliableQueue存在许多锁定问题。

如果您不关心订单,请使用ReliableConcurrentQueue。有关两种队列类型之间的更多详细信息,请参阅此article