MSMQ通过事务接收 - 回滚不再使消息可用

Joh*_*nCC 9 .net c# msmq transactions message-queue

我在一个名为"MessageQueueReceive"的类中有这个.

public MessageQueueTransaction BlockingReceive(out Message message)
{
    MessageQueueTransaction tran = null;
    message = null;

    tran = new MessageQueueTransaction();

    tran.Begin();
    try
    {
        message = Queue.Receive(new TimeSpan(0, 0, 5), tran);
    }
    catch (MessageQueueException ex)
    {
        // If the exception was a timeout, then just continue
        // otherwise re-raise it.
        if (ex.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)
            throw ex;
    }

    return tran;

}
Run Code Online (Sandbox Code Playgroud)

然后我的处理循环有: -

while (!Abort)
{
    try
    {
        tran = this.Queue.BlockingReceive(out msg);

        if (msg != null)
        {
            // Process message here

            if (tran != null)
                tran.Commit();
        }
    }
    catch (Exception ex)
    {
        if (tran != null)
            tran.Abort();

    }
}
Run Code Online (Sandbox Code Playgroud)

控制面板工具显示我正在使用的消息队列是事务性的.日记帐队列未启用.

此代码创建队列: -

private static MessageQueue CreateMessageQueue(string queueName, bool transactional = false)
{
    MessageQueue messageQueue = MessageQueue.Create(queueName, transactional);
    messageQueue.SetPermissions("Administrators", MessageQueueAccessRights.FullControl,
            AccessControlEntryType.Allow);
    return messageQueue;
}
Run Code Online (Sandbox Code Playgroud)

调用此参数时,事务参数设置为"true".

我发现当在处理消息期间发生异常时,会调用tran.Abort,但此时我希望将消息返回到队列中.但是,这种情况并没有发生,消息也会丢失.

我错过了一些明显的东西吗 谁能看到我做错了什么?

Joh*_*nCC 5

感谢所有的评论.我确实重新组织了我的代码,正如Russell McClure建议的那样,我试图创建简单的测试用例,但无法重现问题.

最后,问题根本不在我看的地方(这种情况多久发生一次?).

在我的管道中,我有一个重复的消息检查器.我的系统处理的"消息"来自WAN上的远程设备,有时候线路上的消息是重复的.

当从MSMQ中提取消息时,它将通过重复检查程序传递给数据库写入程序.如果数据库写程序失败,则检查的重复项不会从其表中删除哈希.当进程再次尝试循环时,它将从队列agan获取相同的消息,因为MSMQ事务已在数据库写入程序失败时回滚.但是,在第二次尝试时,重复检查器会发现它之前已经看过该消息,并以静默方式吞下它.

解决方法是让重复检查器发现来自链中下一个链接的异常,并回滚它所做的任何事情.