Ruurd Boeke

I'm building an oracle persistence service and integrating it within our own datalayer. We are migrating a huge project toward proces orchestration with WF. I'm forced to use oracle.
The software has it's own transaction management build in, using nesting and all the stuff that nowadays is common. However, we are not really willing to change our current approach, since it has worked well for us for years.

We're now testing our persistence service with oracle and are seeing that the runtime, when starting up, is enlisting our connection into a System.Transactions.Transaction. This gives us major problems, since we are not using that namespace at all, but instead have a framework that will begin an oracle transaction on the connection itself. Parallel transactions are not allowed and certainly not wanted.

The way out seems to be to build our own WorkflowBatchcommit service, which should allow for your own transaction management. Having finished that, we are getting an exception that there is no ambient transaction!!

The exception is caused by the workflow executor (talk about code smells... that class is way too big ).

private void DoResourceManagerCommit()
{
if (null == Transaction.Current)

{
throw new Exception(ExecutionStringManager.NullAmbientTransaction);
}
this.ResourceManager.Commit();
}

So, the question is: what use is it for us to build our own workflowcommitbatch service, if we are then forced to use the Transactions namespace.
Our transactions are of type OracleTransaction, and are not inherited from the new Transaction class.

This check seems to be really out of place.

Any backgroundinformation about why the WorkflowExecutor feels the need to enforce something, that does not seems to be it's responsibility, are appreciated!

Our current solution is to simply not let the connection enlist into the TransactionScope.

Thanks,

Ruurd Boeke




Re: Windows Workflow Foundation [OraclePersistence service] WF forces me to use transactionscope, instead of letting me decide

Joel West

The WorkflowCommitWorkbatchService is intended as a pluggability point for custom error handling around work batch commit failures. It is not intended as a mechanism for substituting the type of transaction (WF has direct knowledge of the type of transaction used because it needs to do special handling to provide transactional support to the activity execution model - specifically managing the transaction as the thread of execution enters and leaves both activities and the workflow itself).

To the problem at hand - WF is not explicitly enlisting your connection in the active transaction. Enlistment is done by transactional ResourceManagers such as SqlConnection. They look at Transaction.Current and if it is non-null they can decide to participate in it. WF is not a resource manager. We set Transaction.Current so that resouce managers can find it but something that you are using (most likely your connection) is actually making the decision to do the enlistment.

There are two possible ways out of this. First, if possible, turn transaction enlistment off on whatever class is enlisting. SqlConnection, for example, allows you to do this by including "Enlist=false" in the connection string. Your connection class may have a similar option. If that is not available you can put a suppressing TransactionScope around your connection code with a using block. This does require use of System.Transactions types however. With one of these in place you should be able to use the default commit workbatch service. We will create a transaction but you can simply ignore it.

Hope this helps,

Joel West
MSFTE - SDE in WF runtime and hosting

This posting is provided "AS IS" with no warranties, and confers no rights





Re: Windows Workflow Foundation [OraclePersistence service] WF forces me to use transactionscope, instead of letting me decide

Ruurd Boeke

it helps ;-)

It is interesting to hear you say that the WorkflowCommitWorkbatchService is intended for custom error handling, whilst it could be used so well as a point to get your own transactionmanagement going.

Anyway, indeed our resourcemanagement can opt out of auto-enlisting, which is what I've done. I hadn't thought of the supressing transactionscope!