|
Apologies in advance this might be quite a complex one! I should say at the outset that I don't want someone to write my solution for me, just am trying to understand a bit more about how to achieve transactionality in WF.
I'm currently trying to pilot an STP engine using Workflow Foundation to prove its suitability. Everything in the engine is driven using transactional MSMQ queues. It's essential that no information is lost, and that the workflows remain in a consistent state with the contents of the queue. These are the scenarios I'm trying to tackle at the moment:
1. A message arrives on a queue and triggers the creation of a new workflow.
2. A message arrives on a queue and is passed into a waiting workflow.
3. A workflow sends a message on a queue.
In all three the two actions (a queue action, and a workflow action) must happen as part of one atomic transactional unit, so in my mind the queue operation must be linked up with the persistence of the workflow.
The approach I've tried to follow for 2 and 3 is to tie into the IPendingWork and IWorkBatch capabilities of WF. I wrap the MSMQ transactions in a shim class that let it tie into System.Transaction, then add these as pending work items. When the IPendingWork implementing service is called to commit, I try to tie the MSMQ transactions into the transaction that gets passed into IPendingWork.Commit, using transaction.EnlistPromotableSinglePhase. The problem I face here is the the MSMQ transactions cannot be promoted.
I could take the simpler approach and when IPendingWork commits, just commit the MSMQ transactions at that moment in time. What I'm worried about is that if the computer crashes during the commit operation, some of the messages will be sent / or removed from the queue, and some will not. Thus my workflow and queue states will be inconsistent.
Is there something I'm missing? Am I scuppered by the fact the MSMQ does not support promotable transactions or am I doing something wrong on the WF front? If the former I suppose I can use SQL Server 2005 as an intermediary between MSMQ and WF, as SQL Server transactions are promotable.
On scenario 1, I'm lost as to what to do. As far as I can see there doesn't appear to be a similar IPendingWork mechanism for the creation of workflows. So my questions here are, when a workflow is created, is it persisted immediately, and is there a way of tying other transactions into this process?
One solution I can think of would be to pass in the MSMQ transactions as arguments to the workflow, then add a custom activiity with the [PersistOnClose] attribute which adds the transactions to the batch. This seems a little messy to me - is there a better way?
Any help will be much appreciated!
|