locked
TransactedReceiveScope - when does the Transaction Commit? RRS feed

  • Question

  • Scenario:

    We have a wcf workflow with a client that does NOT use transactionflow.
    The workflow contains several sequential TransactedReceiveScopes (using content-based correlation).
    The TransactedReceiveScopes contain custom db operations.

    Observations:

    When we run SQL profiler against the first call, we see all the custom db calls, and the SaveInstance call in the profile trace.

    We've noticed that, even though the SendReply is at the very end of TransactedReceiveScope, sometimes the sendreply occurs a good 10 seconds before the transaction gets committed.

    We tried changing the TimeToPersist and TimeToUnload to zero, but as expected, that had no effect. (The trace shows the SaveInstance happening immediately anyway, but rather the commit seems to be delayed).

    Questions:

    Are our observations correct?

    At what point is the transaction committed? Is this like garbage collection - i.e. it commits some time later when it's not busy?

    Is there any way to control the commit delay, or is the only way to do this to use transactionflow from the client (anc then it should all commit when the client commits, including the persist).

     

    Tuesday, February 22, 2011 2:09 PM

All replies

  • Hi,

    ->"The TransactedReceiveScopes contain custom db operations."
    TransactedReceiveScope activity enables you to flow a transaction into a workflow or dispatcher created server side transactions.
    To enable db transaction.  Please try TransactionScope activity.

    Regards
    MSDN Community Support
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    This posting is provided "AS IS" with no warranties, and confers no rights. My Blog: http://xhinker.com
    Microsoft Windows Workflow Foundation 4.0 Cookbook
    Monday, February 28, 2011 6:57 AM
  • Thanks Andrew.

    Are you saying that a TransactedReceiveScope should only EVER be used in the case of flowing a transaction from another application?

    If that is what you are saying, then why doesn't the TransactedReceiveScope require a transaction? i.e. why doesn't it throw an error if it does not receive a transaction?

     

    Monday, February 28, 2011 6:19 PM
  • Hi,

    We have a similar situation.

    We want to start a Workflow service within a transaction and we use TrasanctedReceiveScope for that purpose. It looks like this:

    TransactedReviceScope

    {

         Request{

                         Receive

                      }

       Body{

                   Sequence {Code activity, SendReplyToReceive}

              }

    }

    The service is called from another application with flowing transaction and after the workflow service instance is started and the control flow is returned, we do the Tx commit in the calling application. The problem is that occasionally when we try to commit the Tx in the calling application, we receive "The transaction has aborted." exception. We investigated the problem (With sql profiler and MSDTC trace logs) and found out that when we try to commit, the commit i issued to the coordinator, but after that, the Workflow Engine try to persist the workflow in the same transaction (witch seems to be properly except the time the WF Engine tries to persist the instance). But that transaction has completed and throws an exception in the workflow engine: System.Data.SqlClient.SqlException: Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.

    The full exception with callstack is this:

        ProcessId=3724
        LogicalOperationStack=
        DateTime=2013-02-14T07:23:42.2862879Z
        Timestamp=951369629681
        Callstack=   at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
       at System.Environment.get_StackTrace()
       at System.Diagnostics.TraceEventCache.get_Callstack()
       at System.Diagnostics.TraceListener.WriteFooter(TraceEventCache eventCache)
       at System.Diagnostics.TraceSource.TraceData(TraceEventType eventType, Int32 id, Object data)
       at System.Transactions.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType type, String code, String description, TraceRecord trace, Exception exception, Guid& activityId, Boolean emitTransfer, Object source)
       at System.Transactions.Diagnostics.TransactionAbortedTraceRecord.Trace(String traceSource, TransactionTraceIdentifier txTraceId)
       at System.Transactions.TransactionStatePromotedAborted.EnterState(InternalTransaction tx)
       at System.Transactions.InternalTransaction.DistributedTransactionOutcome(InternalTransaction tx, TransactionStatus status)
       at System.Transactions.Oletx.RealOletxTransaction.FireOutcome(TransactionStatus statusArg)
       at System.Transactions.Oletx.OutcomeEnlistment.InvokeOutcomeFunction(TransactionStatus status)
       at System.Transactions.Oletx.OletxTransactionManager.ShimNotificationCallback(Object state, Boolean timeout)
       at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)
    System.ServiceModel Warning: 131076 : http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.TraceHandledException.aspxHandling an exception. Exception details: System.OperationCanceledException: An error processing the current work item has caused the workflow to abort.  See the inner exception for details. ---> System.Runtime.DurableInstancing.InstancePersistenceCommandException: The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}SaveWorkflow was interrupted by an error. ---> System.Data.SqlClient.SqlException: Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.
       at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.DurableInstancing.SqlWorkflowInstanceStoreAsyncResult.SqlCommandAsyncResultCallback(IAsyncResult result)
       --- End of inner exception stack trace ---
       at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.Runtime.ActivityExecutor.CompleteTransactionWorkItem.OnPersistComplete(IAsyncResult result)
       --- End of inner exception stack trace ---/LM/W3SVC/7/ROOT/WAIS.DocumentServices.Workflows.EGovPlovdiv-1-130053002192442684System.OperationCanceledException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089An error processing the current work item has caused the workflow to abort.  See the inner exception for details.   at System.Runtime.Diagnostics.EtwDiagnosticTrace.WriteExceptionToTraceString(XmlTextWriter xml, Exception exception, Int32 remainingLength, Int32 remainingAllowedRecursionDepth)
       at System.Runtime.Diagnostics.EtwDiagnosticTrace.ExceptionToTraceString(Exception exception, Int32 maxTraceStringLength)
       at System.Runtime.Diagnostics.EtwDiagnosticTrace.GetSerializedPayload(Object source, TraceRecord traceRecord, Exception exception, Boolean getServiceReference)
       at System.Runtime.TraceCore.HandledExceptionWarning(EtwDiagnosticTrace trace, String param0, Exception exception)
       at System.ServiceModel.Activities.Dispatcher.WorkflowServiceInstance.AbortInstance(Exception reason, Boolean isWorkflowThread, Boolean shouldTrackAbort)
       at System.ServiceModel.Activities.Dispatcher.WorkflowServiceInstance.OnRequestAbort(Exception reason)
       at System.Activities.Runtime.ActivityExecutor.AbortWorkflowInstance(Exception reason)
       at System.Activities.Runtime.ActivityExecutor.FinishWorkItem(WorkItem workItem)
       at System.Activities.Runtime.ActivityExecutor.CompleteTransactionWorkItem.OnPersistComplete(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
       at System.Activities.DurableInstancing.TestDatabaseVersionAndRunAsyncResult.InstanceCommandCompleteCallback(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)
       at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
       at System.Threading.Tasks.Task.Execute()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
       at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
       at System.Threading.ThreadPoolWorkQueue.Dispatch()
    System.OperationCanceledException: An error processing the current work item has caused the workflow to abort.  See the inner exception for details. ---> System.Runtime.DurableInstancing.InstancePersistenceCommandException: The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}SaveWorkflow was interrupted by an error. ---> System.Data.SqlClient.SqlException: Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.
       at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.DurableInstancing.SqlWorkflowInstanceStoreAsyncResult.SqlCommandAsyncResultCallback(IAsyncResult result)
       --- End of inner exception stack trace ---
       at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.Runtime.ActivityExecutor.CompleteTransactionWorkItem.OnPersistComplete(IAsyncResult result)
       --- End of inner exception stack trace ---System.Runtime.DurableInstancing.InstancePersistenceCommandException, System.Runtime.DurableInstancing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}SaveWorkflow was interrupted by an error.   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.Runtime.ActivityExecutor.CompleteTransactionWorkItem.OnPersistComplete(IAsyncResult result)System.Runtime.DurableInstancing.InstancePersistenceCommandException: The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}SaveWorkflow was interrupted by an error. ---> System.Data.SqlClient.SqlException: Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.
       at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.DurableInstancing.SqlWorkflowInstanceStoreAsyncResult.SqlCommandAsyncResultCallback(IAsyncResult result)
       --- End of inner exception stack trace ---
       at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.Runtime.ActivityExecutor.CompleteTransactionWorkItem.OnPersistComplete(IAsyncResult result)System.Data.SqlClient.SqlException, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.DurableInstancing.SqlWorkflowInstanceStoreAsyncResult.SqlCommandAsyncResultCallback(IAsyncResult result)System.Data.SqlClient.SqlException (0x80131904): Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.
       at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at System.Activities.DurableInstancing.SqlWorkflowInstanceStoreAsyncResult.SqlCommandAsyncResultCallback(IAsyncResult result)
    ClientConnectionId:5fdf95cf-9ae4-4f9f-817b-09289f3c966aHelpLink.ProdNameMicrosoft SQL ServerHelpLink.ProdVer11.00.2100HelpLink.EvtSrcMSSQLServerHelpLink.EvtID8525HelpLink.BaseHelpUrlhttp://go.microsoft.com/fwlinkHelpLink.LinkId20476

    The problem for now occurs only when the workflow service has not been used or IIS has been restarted.

    We think that the problem is that when the Control flow is returned to the calling application (with SendReplyToRecive), the workflow continues to process the rest of the WF program to the end of the TransactedReceiveScope. At the end of the TransactedReceiveScope, the WF engine do a persist of the workflow instance and commits the dependant transaction. We suspect that sometimes the WF engine is not fast enough to do the persist before we try to commit from the calling application. Then we receive the "Transaction has aborted exception". The same situation can be simulated when we add a Delay activity in the body of the TRS activity after the SendReplyToReceive, then we always receive the "Transaction has aborted " exception.

    Is there a solution to this situation or we have done something wrong !?

    If this behaviour is by design, then how is supposed to be used with flowing transaction !?!?

    Best regards

    Thursday, February 21, 2013 8:32 AM