I have an ASP.NET MVC app which uses NH (2.1) and RSB (compiled from
git). I would like to push database work and message sending into one
transaction. That's why I open a TransactionScope in the
Application_BeginRequest and dispose in the Application_EndRequest.
protected void Application_BeginRequest()
{
HttpContext.Current.Items[TransactionKey] = new
TransactionScope
();
CurrentSessionContext.Bind(factory.OpenSession());
}
protected void Application_EndRequest()
{
if (CurrentSessionContext.HasBind(factory))
CurrentSessionContext.Unbind(factory).Dispose();
var scope = (TransactionScope)HttpContext.Current.Items
[TransactionKey];
if(scope != null)
{
scope.Complete();
scope.Dispose();
}
}
In the controller action I have some stuff like:
public ActionResult Submit(NewSolutionForm model)
{
var submission = new Submission
{
// omitted for clarity
};
session.Save(submission);
bus.Send(new JudgeSubmission {SubmissionId =
submission.Id});
return this.RedirectToAction(x => x.ViewStatus
(submission.Problem.Contest.Id));
}
session is injected by the container.
The problem is I get InvalidOperationException:
The operation is not valid for the current state of the enlistment.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The operation is
not valid for the current state of the enlistment.
Source Error:
Line 140: {
Line 141: scope.Complete();
Line 142: scope.Dispose();
Line 143: }
Line 144: }
Source File: H:\Projects\NeJudge\SRC\Web\Global.asax.cs Line: 142
Stack Trace:
[InvalidOperationException: The operation is not valid for the current
state of the enlistment.]
System.Transactions.EnlistmentState.InternalIndoubt
(InternalEnlistment enlistment) +40
System.Transactions.VolatileDemultiplexer.BroadcastInDoubt
(VolatileEnlistmentSet& volatiles) +37
System.Transactions.TransactionStatePromotedIndoubt.EnterState
(InternalTransaction tx) +86
System.Transactions.TransactionStatePromotedBase.InDoubtFromEnlistment
(InternalTransaction tx) +19
System.Transactions.DurableEnlistmentDelegated.InDoubt
(InternalEnlistment enlistment, Exception e) +59
System.Transactions.SinglePhaseEnlistment.InDoubt(Exception e) +193
System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit
(SinglePhaseEnlistment enlistment) +485
System.Transactions.TransactionStateDelegatedCommitting.EnterState
(InternalTransaction tx) +157
System.Transactions.TransactionStateDelegated.BeginCommit
(InternalTransaction tx, Boolean asyncCommit, AsyncCallback
asyncCallback, Object asyncState) +47
System.Transactions.CommittableTransaction.Commit() +173
System.Transactions.TransactionScope.InternalDispose() +328
System.Transactions.TransactionScope.Dispose() +1607
Web.NeApplication.Application_EndRequest() in H:\Projects\NeJudge
\SRC\Web\Global.asax.cs:142
[TargetInvocationException: Exception has been thrown by the target of
an invocation.]
System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object
[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes,
RuntimeTypeHandle typeOwner) +0
System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[]
arguments, Signature sig, MethodAttributes methodAttributes,
RuntimeTypeHandle typeOwner) +71
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture,
Boolean skipVisibilityChecks) +350
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+29
System.Web.Util.ArglessEventHandlerProxy.Callback(Object sender,
EventArgs e) +42
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute
() +68
System.Web.HttpApplication.ExecuteStep(IExecutionStep step,
Boolean& completedSynchronously) +75
I was not able to reproduce the bug in a separate application. There
it works just fine.
Any clues why this happens?
Any ideas if I should put the database work and message sending in one
transaction at all? Anybody did that successfully?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Rhino Tools Dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/rhino-tools-dev?hl=en
-~----------~----~----~----~------~----~------~--~---