<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: System.Transactions and Workflows</title>
	<atom:link href="http://winterdom.com/2007/07/systemtransactionsandworkflows/feed" rel="self" type="application/rss+xml" />
	<link>http://winterdom.com/2007/07/systemtransactionsandworkflows</link>
	<description>by dæmons be driven</description>
	<lastBuildDate>Sat, 13 Mar 2010 12:02:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Tomas Restrepo</title>
		<link>http://winterdom.com/2007/07/systemtransactionsandworkflows/comment-page-1#comment-265</link>
		<dc:creator>Tomas Restrepo</dc:creator>
		<pubDate>Mon, 16 Jul 2007 11:24:45 +0000</pubDate>
		<guid isPermaLink="false">http://winterdom.com/2007/07/systemtransactionsandworkflows#comment-265</guid>
		<description>Mark: That&#039;s certainly a testament to the power and flexibility of WF. It sure looks like you&#039;ve successfully customized it to work exactly how you want to, in a pretty cool way!
Not all projects, however, can undertake fairly big customizations of the workflow hosting infrastructure such as yours, and even then, circumstances may prevent them from using your specific approach.
</description>
		<content:encoded><![CDATA[<p>Mark: That&#8217;s certainly a testament to the power and flexibility of WF. It sure looks like you&#8217;ve successfully customized it to work exactly how you want to, in a pretty cool way!<br />
Not all projects, however, can undertake fairly big customizations of the workflow hosting infrastructure such as yours, and even then, circumstances may prevent them from using your specific approach.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mark Johnson</title>
		<link>http://winterdom.com/2007/07/systemtransactionsandworkflows/comment-page-1#comment-264</link>
		<dc:creator>Mark Johnson</dc:creator>
		<pubDate>Mon, 16 Jul 2007 09:59:11 +0000</pubDate>
		<guid isPermaLink="false">http://winterdom.com/2007/07/systemtransactionsandworkflows#comment-264</guid>
		<description>Need to clarify that the time span from one Event handler to the next, must be less than the transaction timeout.  Obviously this is a significant constraint if your workflow has many complex activities between EventHandlers.  But it seems to me like workflows are mostly waiting for input from external actors and the activities themselves should execute in a reasonable timeframe.
Anothe Caveat:  The default TransactionScopeActivity will stop working correctly.  This could be overcome be creating a custom TransactionScopeActivity or by further modification to the custom SqlWorkflowPersistenceService.
</description>
		<content:encoded><![CDATA[<p>Need to clarify that the time span from one Event handler to the next, must be less than the transaction timeout.  Obviously this is a significant constraint if your workflow has many complex activities between EventHandlers.  But it seems to me like workflows are mostly waiting for input from external actors and the activities themselves should execute in a reasonable timeframe.<br />
Anothe Caveat:  The default TransactionScopeActivity will stop working correctly.  This could be overcome be creating a custom TransactionScopeActivity or by further modification to the custom SqlWorkflowPersistenceService.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mark Johnson</title>
		<link>http://winterdom.com/2007/07/systemtransactionsandworkflows/comment-page-1#comment-263</link>
		<dc:creator>Mark Johnson</dc:creator>
		<pubDate>Mon, 16 Jul 2007 09:39:12 +0000</pubDate>
		<guid isPermaLink="false">http://winterdom.com/2007/07/systemtransactionsandworkflows#comment-263</guid>
		<description>On our current project, the requirement was that workflows be entirely transactional.  These are long running statemachine workflows.  The following are the steps required:
1) Use ManualWorkflowSchedulerService
2) By default WF does not flow in ambient transactions, so a custom TransactionService (a double dictionary keyed by thread and instanceID) must be used.  Set the Transaction.Current in the service for the current thread before invoking an event on the workflow.
3) Exceptions do not flow out of the WF runtime, so a custom exception service is required (very similar to the transaction service) to re-throw exceptions after an event is raised on the workflow.
4) The default SqlWorkflowPersistenceService must be customized (Reflector works good) to set &#039;Enlist=true&#039; (this is required for loading workflow instance so it is part of the same transaction to prevent deadlocks)
5) Create a base activity that all activities should derive from.  This simply creates a TransactionScope (using the transaction stored in the TransactionService for the thread and instance) and calls the derived class&#039;s &#039;DoExecute&#039; method.
6) Instance.Unload must occur after firing an event and within the same TransactionScope
If any exception occurs during an Activity&#039;s Execute method, the transaction is rolled back and the State Machine is returned to it&#039;s original state.  This setup will allow any number of events to be invoked on any number of Workflow Instances within the same transaction.  A transaction is only valid on the thread it was created (at least the way we built it).
Even though the workflow is long running (many years), each activity must execute before the transaction times out (3 minutes in our case)
</description>
		<content:encoded><![CDATA[<p>On our current project, the requirement was that workflows be entirely transactional.  These are long running statemachine workflows.  The following are the steps required:<br />
1) Use ManualWorkflowSchedulerService<br />
2) By default WF does not flow in ambient transactions, so a custom TransactionService (a double dictionary keyed by thread and instanceID) must be used.  Set the Transaction.Current in the service for the current thread before invoking an event on the workflow.<br />
3) Exceptions do not flow out of the WF runtime, so a custom exception service is required (very similar to the transaction service) to re-throw exceptions after an event is raised on the workflow.<br />
4) The default SqlWorkflowPersistenceService must be customized (Reflector works good) to set &#8216;Enlist=true&#8217; (this is required for loading workflow instance so it is part of the same transaction to prevent deadlocks)<br />
5) Create a base activity that all activities should derive from.  This simply creates a TransactionScope (using the transaction stored in the TransactionService for the thread and instance) and calls the derived class&#8217;s &#8216;DoExecute&#8217; method.<br />
6) Instance.Unload must occur after firing an event and within the same TransactionScope<br />
If any exception occurs during an Activity&#8217;s Execute method, the transaction is rolled back and the State Machine is returned to it&#8217;s original state.  This setup will allow any number of events to be invoked on any number of Workflow Instances within the same transaction.  A transaction is only valid on the thread it was created (at least the way we built it).<br />
Even though the workflow is long running (many years), each activity must execute before the transaction times out (3 minutes in our case)</p>
]]></content:encoded>
	</item>
</channel>
</rss>
