murk

Hello, I am have a synchronous state machine workflow (using ManualWorkflowSchedulerService). I have a need to have any transactions within the workflow itself, enlist into the Transaction.Current of the caller that invoked the ExternalEvent.

A simple example depicting the behavior I am seeing (The Transaction.Current is null when the CallExternalMethodActivites are invoked)

Code Snippet

[Test]

public void PropagateTransaction()

{

//Create workflow with SqlPersistence & ManualWorkflowSchedulerService. details left out. Wraps ExternalEvents.

WorkflowInstanceWrapper workflow1 = GetNewWorkflow();

TransactionOptions opt = new TransactionOptions();
opt.IsolationLevel = IsolationLevel.RepeatableRead;
using(TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, opt))

{

//Transition to State1 and CallExternalMethodActivity invokes CEM1 (below)

workflow1.RaiseState1Event();

//Transition to State2 and CallExternalmethodActivity invokes CEM2

workflow2.RaiseState2Event();

} //Auto roll back to before entering state 1

}

.......

public DataService : IExternalDataExchangeHandler

{

public void CEM1()

{

Debug.Print(Transaction.Current); //null

}

public void CEM2()

{

Debug.Print(Transaction.Current); //null

}

}

Basically, I just need the outer most Transaction to be available to all activities within the Workflow (TransactionScopeActivity does not have a big enough scope). One way I can think of is to pass the Transaction.Current when invoking the ExternalMethods, but it seems unnecessary if the workflow is running synchronously on the same thread as the caller.



Re: Windows Workflow Foundation Enlist workflow in outside transactions

Roman Kiss

murk,

- have a look at this thread

- in your case, when the State2 failed, it should be a transition to the State3 for compensation activity instead of using a transaction scope across the States and locking all resources in the State1.

Thanks

Roman






Re: Windows Workflow Foundation Enlist workflow in outside transactions

murk

Thanks Roman, that offers quite a bit of enlightenment, but right now I have Database insert/updates that occur in the CallExternalMethod calls.

If I do decide to add a "CurrentTransaction" property to the EventArgs of the ExternalEvent calls and a "currentTransaction" parameter to the ExternalMethod calls, is there a potential problem I don't mind that State2 will lock resources in State1. I have tested it and it seems to work as expected, but there may be some edge cases I am not seeing (Crash mid transaction etc.).