NServiceBus MSDTC遇到了麻烦

时间:2011-01-20 09:04:03

标签: nservicebus

我在这里写这篇文章是希望有人可以帮助我。

我正在尝试在ASP.NET MVC应用程序上实现NServiceBus。我已经完成了每一步,以确保一切正常。我有一个事件将Job ID传递给我的处理程序,然后执行Linq-to-Sql查询并查找作业,然后通过电子邮件发送警报。这个过程非常简单。

但是,我不能为我的生活让MSDTC工作。我继续收到以下错误:

以下是我配置总线的方法:

 Bus = NServiceBus.Configure.WithWeb()
            .Log4Net()
            .DefaultBuilder()
            .XmlSerializer()
            .MsmqTransport()
                .IsTransactional(false)
                .PurgeOnStartup(false)
            .UnicastBus()
                .ImpersonateSender(false)
            .CreateBus()
            .Start();

我没有使用交易,所以我知道甚至不应该调用MSDTC。

我的处理程序代码如下:

public void Handle(ApplyJobMessage message)
    {
        if (message != null)
        {
            using(var context = new MyContext())
            {
                JobPosting posting = (from c in context.JobPostings
                 where c.JobPostingId == message.JobId
                 select c).SingleOrDefault();
            }

端点配置如下:

public class MessageEndpoint : IConfigureThisEndpoint, AsA_Server, IWantToRunAtStartup

一切都很好。当我这样做时,消息正确到达:

Bus.Send(message);

但是,MSDTC错误如图所示:

    2011-01-20 00:55:09,744 [Worker.5] ERROR NServiceBus.Unicast.UnicastBus [(null)]
 <(null)> - JobApplicationHandler Failed handling message.
System.Runtime.InteropServices.COMException (0x8004D02A): The MSDTC transaction
manager was unable to push the transaction to the destination transaction manage
r due to communication problems. Possible causes are: a firewall is present and
it doesn't have an exception for the MSDTC process, the two machines cannot find
 each other by their NetBIOS names, or the support for network transactions is n
ot enabled for one of the two transaction managers. (Exception from HRESULT: 0x8
004D02A)
   at **System.Transactions.Oletx.ITransactionShim.Export**(UInt32 whereaboutsSize,
Byte[] whereabouts, Int32& cookieIndex, UInt32& cookieSize, CoTaskMemHandle& coo
kieBuffer)
   at System.Transactions.TransactionInterop.GetExportCookie(Transaction transac
tion, Byte[] whereabouts)
2011-01-20 00:55:09,749 [Worker.5] WARN  NServiceBus.Unicast.Transport.Msmq.Msmq
Transport [(null)] <(null)> - Failed raising 'transport message received' event
for message with ID=9cb4b136-e110-4b87-81f6-ee4cd3fcaf46\6151
System.Reflection.TargetInvocationException: Exception has been thrown by the ta
rget of an invocation. ---> System.Transactions.TransactionManagerCommunicationE
xception: Communication with the underlying transaction manager has failed. --->
 System.Runtime.InteropServices.COMException (0x8004D02A): The MSDTC transaction
 manager was unable to push the transaction to the destination transaction manag
er due to communication problems. Possible causes are: a firewall is present and
 it doesn't have an exception for the MSDTC process, the two machines cannot fin
d each other by their NetBIOS names, or the support for network transactions is
not enabled for one of the two transaction managers. (Exception from HRESULT: 0x
8004D02A)
   at System.Transactions.Oletx.ITransactionShim.Export(UInt32 whereaboutsSize,
Byte[] whereabouts, Int32& cookieIndex, UInt32& cookieSize, CoTaskMemHandle& coo
kieBuffer)
   at System.Transactions.TransactionInterop.GetExportCookie(Transaction transac
tion, Byte[] whereabouts)
   --- End of inner exception stack trace ---
   at System.Transactions.TransactionInterop.GetExportCookie(Transaction transac
tion, Byte[] whereabouts)
   at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transacti
on transaction, Byte[] whereAbouts)
   at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transa
ction)
   at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transacti
on transaction)
   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection ownin
gObject)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionU
ser user)
   at System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe()
   at System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode()
   at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider
.Execute(Expression query)
   at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Express
ion expression)
   at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)

我尝试过DTC ping并且它成功运行所以我知道MSDTC不是问题。我已经读过NHibernate与NServiceBus有类似的问题,但是我无法在LINQ to SQL上绘制任何相似内容。

对此事的任何帮助都将非常感激。

4 个答案:

答案 0 :(得分:11)

接受的解决方案实际上是解决问题的方法。我建议您使用DTCPing工具正确设置MSDTC并找出潜在问题。

查看此帖子了解更多信息:

MSDTC非常模糊,祝你好运!

答案 1 :(得分:10)

我有一个类似的问题,发现原因是更多的LINQ-to-SQL而不是NServiceBus。如果查看堆栈跟踪,您将看到根本原因是您的LINQ和SqlClient库,而不是NSB。我最终使用的解决方案,可能会或可能不会对您有用,具体取决于您的数据访问对事务的重要性,是在我的LINQ to SQL代码中明确地关闭事务。就我而言,我只是使用LINQ to SQL调用存储过程,代码如下:

        public void Save(SomeEvent someEvent)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                _loggingDatabaseConnection.DataContext.log_ClickInsert(
someEvent.LogDate, 
someEvent.Id, 
someEvent.OtherStuffGoesHere);
            }

这里的重要部分是TransactionScope和TransactionScopeOption.Suppress。这可确保LINQ to SQL不会尝试使用DTC将调用登记到事务中。这是我的消息处理程序(NServiceBus Generic Host)中的解决方案。

答案 2 :(得分:6)

我注意到您将NServiceBus配置为服务器,这意味着 是事务性的。我认为你所拥有的是一个非事务性的Web应用程序,它将消息发送到事务服务器。

答案 3 :(得分:1)

我记得自己在MSDTC上遇到过问题,但是对于我的生活来说,找不到我所引用的博客/帖子/解决问题。无论如何,如果那个ping程序正在运行,那就有点奇怪了。我可能添加的一个建议是尝试添加该行,

.RunCustomAction(() => 
  NServiceBus.Configure.Instance.Configurer.ConfigureProperty<MsmqSubscriptionStorage>(
  msg => msg.DontUseExternalTransaction, true))

.CreateBus()行之前。如果您使用订阅,这将告诉订阅停止使用交易,这可能是您的问题。但是请注意,这样做会降低您的订阅可靠性,因此请勿在紧急情况下使用它。