WWF Persistance Status
I have a workflow which having a while loop inside that I have an activity called Handle External Event, which will receives inputs from some windows application.
When ever inputs come I used start a workflow and load the workflow for current situations.
I have situations like, some time I have to hold the current workflow instance (dehydration) and start new workflow instance. WF internally updates the workflow persistence details into Workflow – DB.
When ever workflow executes, I have to store the input values into my application database. So I am calling a database call( call to Data access Layer) from my External activity.
The problem I am facing is after updating my application database workflow is not at all updating the persistence status in the Workflow DB. Hence I cannot load the old work flow, hence the status for the old workflow instance is not updated in WF DB.
Can any one suggest a solution for this?
Can I make DB call from my Workflow activity (Handle External Event?)
hanks in advance
Umeshnath
Answers
The best way to do your database work is to write it in the same transaction that is used to persist the workflow instance. That way your workflow state and your application database state will either both be visible or neither will be visible (you'll also be atomic in your writes so that a failure can't leave your app db state out of sync with your workflow persistence state).
There are two ways to include your work in persistence transactions. The first is to use a TransactionScopeActivity (TSA) in your workflow. Add a code activity as a child of the TSA and do your sql work in the code handler. When the TSA starts the WF runtime creates a System.Transactions.TransactionScope. The db work that you do in your code activity will automatically enlist in this transaction. The TSA completes the workflow instance will be persisted and the persistence service will use the same transaction as the TSA. Voila, you've got an atomic commit of your db work and the persistence work. This is a simple, natural transaction based programming model that is easy to use. However it assumes that you can dictate the structure of your workflow. If you can, by all means, use this approach
The second way is to write a class that implements IPendingWork. Your IPendingWork class will do your database work. In the workflow you can use a code activity (or a custom activity) to construct your IPendingWork class, hand it the data that it needs to write to the db and then add it to the WorkflowRuntime batch using the static WorkEnvironment.Workbatch.Add. When a persistence point occurs every IPendingWork item in the batch will have it's Commit method called. The persistence transaction is passed to Commit so that the work that you do will be consistent with the persistence work. This is a good way to go if you have users writing workflows that you need to run where you can't enforce that they use a TSA. You can write a custom activity that users can put in their workflow. This custom activity will create your IPendingWork class and add it to the batch. At the next persistence point your IPendingWork.Commit will be called and your data will be written atomically with the persistence data. This is a little more complex but it offers a very nice model if you have end users writing your workflows (or other users that may not understand what a TSA is for or when they should use it).
Thanks,
Joel West
MSFTE - SDE in WF runtime and hostingThis posting is provided "AS IS" with no warranties, and confers no rights
All Replies
The best way to do your database work is to write it in the same transaction that is used to persist the workflow instance. That way your workflow state and your application database state will either both be visible or neither will be visible (you'll also be atomic in your writes so that a failure can't leave your app db state out of sync with your workflow persistence state).
There are two ways to include your work in persistence transactions. The first is to use a TransactionScopeActivity (TSA) in your workflow. Add a code activity as a child of the TSA and do your sql work in the code handler. When the TSA starts the WF runtime creates a System.Transactions.TransactionScope. The db work that you do in your code activity will automatically enlist in this transaction. The TSA completes the workflow instance will be persisted and the persistence service will use the same transaction as the TSA. Voila, you've got an atomic commit of your db work and the persistence work. This is a simple, natural transaction based programming model that is easy to use. However it assumes that you can dictate the structure of your workflow. If you can, by all means, use this approach
The second way is to write a class that implements IPendingWork. Your IPendingWork class will do your database work. In the workflow you can use a code activity (or a custom activity) to construct your IPendingWork class, hand it the data that it needs to write to the db and then add it to the WorkflowRuntime batch using the static WorkEnvironment.Workbatch.Add. When a persistence point occurs every IPendingWork item in the batch will have it's Commit method called. The persistence transaction is passed to Commit so that the work that you do will be consistent with the persistence work. This is a good way to go if you have users writing workflows that you need to run where you can't enforce that they use a TSA. You can write a custom activity that users can put in their workflow. This custom activity will create your IPendingWork class and add it to the batch. At the next persistence point your IPendingWork.Commit will be called and your data will be written atomically with the persistence data. This is a little more complex but it offers a very nice model if you have end users writing your workflows (or other users that may not understand what a TSA is for or when they should use it).
Thanks,
Joel West
MSFTE - SDE in WF runtime and hostingThis posting is provided "AS IS" with no warranties, and confers no rights
Hi,
Can you give some sample/ links which help me to understand " IPendingWork " Interface.
Thasnks in advance
Umeshnath
There should be some starting documentation in the current CTP's online help (I say should but I don't have that build in front of me so I might be wrong). However to really dig into it the SDK sample Transactional Service is probably the best thing to look at (in the Samples dir in your SDK install path which by default is C:\Program Files\Microsoft SDKs\Windows Workflow Foundation\Samples\Samples\Technologies\TransactionalService\TransactionalServiceExample). TransactionalService.cs contains the class that implements IPendingWork.
Thanks,
Joel West
MSFTE - SDE in WF runtime and hostingThis posting is provided "AS IS" with no warranties, and confers no rights


