我们遇到了 Rhino 服务总线的问题,即所有事务都被隐式地登记到环境事务 (MSDTC) 中。这暂时没问题,但我们运行了许多长时间运行的进程,这些进程将花费超过一小时(DTC 的最大超时为一小时)。为了解决这个问题,我创建了一个 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 的无方法接口,以使特定命令能够加入环境事务。虽然拥有如此长时间运行的进程并不理想,但这种方法已经解决了我们长期运行事务的直接问题