Note that there are some explanatory texts on larger screens.

plurals
  1. POSending NServiceBus message inside TransactionScope
    text
    copied!<p>I am trying to use NHibernate to save to a database in the same transaction as sending a message on the bus from inside an MVC application:</p> <pre><code>public void DoSomethingToEntity(Guid id) { var session = _sessionFactory.OpenSession(); CurrentSessionContext.Bind(session); using (var transactionScope = new TransactionScope()) { var myEntity = _session.Get(id); myEntity.DoSomething(); _session.Save(myEntity); _bus.Send(myMessage); transactionScope.Complete(); } session.Dispose(); } </code></pre> <p>In the configuration, .MsmqTransport() is set with .IsTransactional(true).</p> <p>If I do this inside a message handler (which is wrapped in its own transaction so does not need the TransactionScope) Then it all works as expected, and if I include an exception, both fail.</p> <p>However, if I do it inside my own transaction in an MVC application, I get the following error after transactionScope.Complete() when leaving the using block.:</p> <p>'The operation is not valid for the current state of the enlistment.'</p> <p>Stack Trace: at System.Transactions.EnlistmentState.InternalIndoubt(InternalEnlistment enlistment) at System.Transactions.VolatileDemultiplexer.BroadcastInDoubt(VolatileEnlistmentSet&amp; volatiles) at System.Transactions.TransactionStatePromotedIndoubt.EnterState(InternalTransaction tx) at System.Transactions.TransactionStatePromotedBase.InDoubtFromEnlistment(InternalTransaction tx) at System.Transactions.DurableEnlistmentDelegated.InDoubt(InternalEnlistment enlistment, Exception e) at System.Transactions.SinglePhaseEnlistment.InDoubt(Exception e) at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment) at System.Transactions.TransactionStateDelegatedCommitting.EnterState(InternalTransaction tx) at System.Transactions.TransactionStateDelegated.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState) at System.Transactions.CommittableTransaction.Commit() at System.Transactions.TransactionScope.InternalDispose() at System.Transactions.TransactionScope.Dispose() at HumanResources.Application.Implementations.HolidayService.Book(BookHolidayRequest request) in C:\Users\paul.davies\Documents\GitHub\EdaCalendarExample\HumanResources.Application\Implementations\HolidayService.cs:line 76 at HumanResources.UI.Controllers.HolidayController.BookUpdate(BookHolidayViewModel viewModel) in C:\Users\paul.davies\Documents\GitHub\EdaCalendarExample\HumanResources.UI\Controllers\HolidayController.cs:line 82 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary<code>2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary</code>2 parameters) at System.Web.Mvc.ControllerActionInvoker.&lt;>c_<em>DisplayClass15.b</em>_12() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)</p> <p><strong>Latest Edit:</strong></p> <p>This code works:</p> <pre><code>public void DoSomethingToEntity(Guid id) { var session = _sessionFactory.OpenSession(); CurrentSessionContext.Bind(session); using (var transactionScope = new TransactionScope()) { var myEntity = _session.Get(id); _bus.Send(myMessage); transactionScope.Complete(); } session.Dispose(); } </code></pre> <p>This code creates the error:</p> <pre><code>public void DoSomethingToEntity(Guid id) { var session = _sessionFactory.OpenSession(); CurrentSessionContext.Bind(session); using (var transactionScope = new TransactionScope()) { var myEntity = _session.Get(id); myEntity.AnyField = "a new value"; _bus.Send(myMessage); transactionScope.Complete(); } session.Dispose(); } </code></pre> <p>Note that I am not saving th entity in either example. The difference is in the second example, I am modifying the entity I have got from NHibernate. This is 100% reproducable.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload