2011-01-20 89 views
8

我在这里写这篇文章,希望有人能帮助我。NServiceBus MSDTC灾难

我想在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平并成功的作品,所以我知道一个事实,即MSDTC ISN”问题。我已经读过NHibernate和NServiceBus有类似的问题,但是我还没有能够用LINQ to SQL来绘制任何类似的问题。

任何有关此事的帮助将不胜感激。

+0

我应该补充一点,当我在本地盒子上试用这个数据库时,一切似乎都奏效。现在我很好奇它为什么不能在远程盒子上使用数据库。 – 2011-01-20 09:32:44

+0

Handler机器和数据库机器的操作系统是什么?数据库机器是否允许入站事务?处理器机器和数据库机器在DTC中设置的认证机制是什么? – 2011-01-20 18:17:15

回答

10

我有一个类似的问题,发现原因比NServiceBus更LINQ到SQL。如果你看看你的堆栈跟踪,你会看到根源是你的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通用主机)解决方案中工作。

1

我记得自己和MSDTC有问题,但是对于我的生活,无法找到博客/帖子/无论我引用什么来解决问题。无论如何,如果这个ping程序正在运行,这有点奇怪。一个建议我可以补充的是就在.CreateBus()行之前尝试添加行,

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

。如果您正在使用订阅,这将告知订阅停止使用交易,这可能是您的问题。不过要注意的是,这样做会使您的订阅不可靠,所以请勿在紧急情况下使用它。

6

我注意到的是,你正在配置NServiceBus作为服务器,这意味着它是交易。我认为你在这里是一个非事务性的Web应用程序,它将消息发送到事务服务器。

+1

如果您标记端点AsA_Server,则它与IsTransactional(true)等效。它实际上覆盖了您设置的任何IsTransactional(false)。也许@AnupMarwadi,你应该把你的端点标记为'AsA_Client'? – 2011-01-25 14:13:39