Rhino Service Bus交易

时间:2013-07-22 20:56:31

标签: .net asp.net-mvc-4 rhino-servicebus

我能够使用Rhino Service Bus和Sql Server Express创建测试应用程序。我有一个MVC 4前端,它创建一条消息并将其发送到队列,并在我的数据库表中创建一条记录。我有一个Windows服务,它从队列中获取消息并写入单独的数据库表。我希望消息发送/数据库写入全部或全部。例如,如果消息发送或数据库写入失败,我希望能够将它们回滚。我尝试在TransactionScope中包装它们,但根据我的测试,即使没有调用scope.Complete,消息也会被发送到队列。

这可能吗?如果是这样,有人能指出我正确的方向吗?

FYI ......队列是MSMQ事务队列

感谢。

2 个答案:

答案 0 :(得分:1)

我在Rhino Service Bus Google网站上发布了同样的问题,得到了Oren的回复。事实证明,RSB将处理事务,但我使用的是IOnewayBus,它不使用DTC。我做了更改以使用IStartableServiceBus,现在一切都按预期工作。

答案 1 :(得分:0)

我们遇到Rhino Service总线的问题,因此所有交易都被列入环境交易(MSDTC)。暂时还可以,但是我们运行了一些长时间运行的进程,这些进程需要一个多小时(DTC的最大超时时间为1小时)。为了解决这个问题,我创建了一个IMessageModule实现,如下所示:

/// <summary>
/// alows commands to opt-in to ambient transaction (MSDTC)
/// </summary>
/// <remarks>will supress by default</remarks>
public class SuppressAmbientTransactionMessageModule : IMessageModule
{

    [ThreadStatic]
    private static TransactionScope transactionScope;

    public void Init(ITransport transport, IServiceBus serviceBus)
    {
        transport.MessageArrived += TransportOnMessageArrived;
        transport.BeforeMessageTransactionCommit += transport_BeforeMessageTransactionCommit;
        transport.BeforeMessageTransactionRollback += transport_BeforeMessageTransactionCommit;
    }

    public void transport_BeforeMessageTransactionCommit(CurrentMessageInformation currentMessageInformation)
    {
        if (!(currentMessageInformation.Message is IWithAmbientTransaction))
        {
            transactionScope.Dispose();
        }
    }

    public void Stop(ITransport transport, IServiceBus bus)
    {
        transport.MessageArrived -= TransportOnMessageArrived;
        transport.BeforeMessageTransactionCommit -= transport_BeforeMessageTransactionCommit;
        transport.BeforeMessageTransactionRollback -= transport_BeforeMessageTransactionCommit;
    }

    public bool TransportOnMessageArrived(CurrentMessageInformation currentMessageInformation)
    {
        if (!(currentMessageInformation.Message is IWithAmbientTransaction))

        {
            transactionScope = new TransactionScope(TransactionScopeOption.Suppress);
        }
        return false;
    }
}

我还创建了一个名为IWithAmbientTransaction的无方法接口,以使特定命令能够在环境事务中登记。这种长期运行流程的方法并不理想,这解决了我们长期运行交易的直接问题