Problems with MSDTC in NServiceBus

I am writing this post here in the hope that someone can help me.

I am trying to implement NServiceBus in an ASP.NET MVC application. I went through every step to make sure everything is connected correctly. I have an event that passes the job ID to my handler, which then executes a Linq-to-Sql query and scans the job, and then sends an email. The process is very simple.

However, I cannot get MSDTC to work in my life. I keep getting the following error:

Here's how I set up my bus:

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

I do not use transactions, so I know that MSDTC does not even need to be called.

My handler code is as follows:

 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(); } 

The endpoint is configured as follows:

 public class MessageEndpoint : IConfigureThisEndpoint, AsA_Server, IWantToRunAtStartup 

Everything works great. The message arrives correctly when I do:

 Bus.Send(message); 

However, the MSDTC error occurs as shown:

  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) 

I tried PTC ping and it works successfully, so I know that MSDTC is not a problem. I read that NHibernate had similar problems with NServiceBus, but I could not draw parallels with LINQ to SQL.

Any help on this would be greatly appreciated.

+8
nservicebus
source share
4 answers

I had a similar problem and found that the reason was more LINQ-to-SQL than NServiceBus. If you look at your stack trace, you will see that the main reason is your LINQ and SqlClient libraries, not the NSB. The solution I ended up using, which may or may not work for you depending on how important it is for your data access, was transactional, was to explicitly disable transactions in my LINQ to SQL code. In my case, I just called the stored procedure using LINQ to SQL, with this code:

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

The important part here is TransactionScope and TransactionScopeOption.Suppress. This ensures that LINQ to SQL does not attempt to invoke a call in a transaction using the DTC. This works in my solution in my message handler (NServiceBus Generic Host).

+10
source share

The decision made is really a workaround for the problem. I suggest you use the DTCPing tool to properly configure MSDTC and find the main problems.

Check out these posts for more information:

MSDTC is pretty obscure, good luck!

+11
source share

What I noticed is that you are setting up NServiceBus as a server, which means that it is transactional. I think that here you have a non-transactional web application that sends messages to the transactional server.

+6
source share

I remember that I have problems with MSDTC, but for all my life I can not find blogs / posts / everything that I referred to to solve the problem. Anyway, if this ping program works, it's a little weird. One suggestion I can add is trying to add a row,

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

immediately before the line .CreateBus() . If you use subscriptions, it means that the subscription will stop using transactions, which may be your problem. However, be careful, so this will make your subscriptions less reliable, so do not use them in critical situations.

+1
source share

Source: https://habr.com/ru/post/651285/


All Articles