<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Florin Lazar - Consistency Checkpoint : DependentTransaction</title><link>http://blogs.msdn.com/florinlazar/archive/tags/DependentTransaction/default.aspx</link><description>Tags: DependentTransaction</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Phase0 in .Net System.Transactions</title><link>http://blogs.msdn.com/florinlazar/archive/2006/04/09/phase0-in-net-system-transactions.aspx</link><pubDate>Sun, 09 Apr 2006 23:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:572035</guid><dc:creator>florinlazar</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/florinlazar/comments/572035.aspx</comments><wfw:commentRss>http://blogs.msdn.com/florinlazar/commentrss.aspx?PostID=572035</wfw:commentRss><wfw:comment>http://blogs.msdn.com/florinlazar/rsscomments.aspx?PostID=572035</wfw:comment><description>&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;In a previous post (&lt;A href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx"&gt;http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx&lt;/A&gt;) I talked about Phase0 and some useful things it allows you to do. Although not referred as Phase0, phase 0 features are available in .Net System.Transactions in two forms. Actually in three, but the third is a derivate. I will make many references here to the &lt;A href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx"&gt;previous post &lt;/A&gt;on Phase0 and thus I recommend reading it first.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;The first form where Phase 0 shows up is&amp;nbsp;through &lt;STRONG&gt;EnlistmentOptions.EnlistDuringPrepareRequired&lt;/STRONG&gt; that you can pass to EnlistVolatile or EnlistDurable methods. This allows you to create new enlistments during Prepare phase (and after Commit was called) and thus it allows you to create the caching resource manager (RM) discussed in the &lt;A href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx"&gt;earlier post&lt;/A&gt;. To create a cache RM, you will first call EnlistVolatile with EnlistmentOptions.EnlistDuringPrepareRequired, and then, during Prepare you will connect to the database to write the updates. The connection to the database will usually call EnlistDurable on the transaction. Similar to Phase0 in the native DTC API, during the Prepare phase, one can enlist again passing EnlistmentOptions.EnlistDuringPrepareRequired which will issue another round of Prepare on that enlistment and so on.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;The second form comes with &lt;STRONG&gt;DependentTransaction&lt;/STRONG&gt;. You get a DependentTransaction by calling the DependentClone method on a transaction object. You can get the other two scenarios enabled by Phase0, “early commit protection” and “async programming” by tweaking the DependentCloneOption to RollbackIfNotComplete and BlockCommitUntilComplete respectively. Then, you signal&amp;nbsp;that the work is done&amp;nbsp;by calling the Complete method of this dependent transaction.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Thus you will write the &lt;A href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx"&gt;DoTransfer&lt;/A&gt; method in .Net as follows:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana color=#0000ff size=2&gt;int DoTransfer(int amount, Transaction tx)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the dependent clone&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DependentTransaction dtx = tx.DependentClone(DependentCloneOption. &lt;STRONG&gt;RollbackIfNotComplete&lt;/STRONG&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=Verdana color=#0000ff size=2&gt;DB1.OpenConnection(tx);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB1.DoDebit(amount);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB2.OpenConnection(tx);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB2.DoCredit(amount);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // signal work complete on the “phase0” enlistment&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dtx.Complete();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;If the DependentTransaction is not Complete-ed before a Commit is issued by the client, the transaction will be aborted.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;The “third” derivate form is &lt;STRONG&gt;TransactionScope&lt;/STRONG&gt; itself. TransactionScope protects you against early commits by automatically handling under the covers a DependentTransaction with RollbackIfNotComplete. That is why TransactionScope is recommended for most of the transactions scenarios. Given this you can write with the same confidence the DoTransfer method as follows:&lt;BR&gt;&lt;BR&gt;&lt;FONT face=Verdana color=#0000ff&gt;int DoTransfer(int amount, Transaction tx)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // creating a TransactionScope by passing in the received transaction&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // this will set tx to be the ambient transaction and&amp;nbsp;create a&amp;nbsp;"rollback" dependent transaction&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;using(TransactionScope ts = new TransactionScope(tx))&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB1.OpenConnection(); // note that now OpenConnection is picking the transaction from the ambient context instead of passing it as a parameter&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB1.DoDebit(amount);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB2.OpenConnection();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB2.DoCredit(amount);&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;BR&gt;&lt;FONT face=Verdana color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ts.Complete();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Other Scenarios enabled and/or made easier by DependentTransaction&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&lt;STRONG&gt;The “Worker Threads Scenario”&lt;/STRONG&gt;&lt;BR&gt;This is explained both at &lt;/FONT&gt;&lt;A href="http://pluralsight.com/blogs/jimjohn/archive/2005/05/01/7923.aspx" mce_href="http://pluralsight.com/blogs/jimjohn/archive/2005/05/01/7923.aspx"&gt;&lt;FONT face=Tahoma size=2&gt;http://pluralsight.com/blogs/jimjohn/archive/2005/05/01/7923.aspx&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Tahoma size=2&gt; and &lt;/FONT&gt;&lt;A href="http://msdn2.microsoft.com/en-US/library/ms229976(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-US/library/ms229976(VS.80).aspx"&gt;&lt;FONT face=Tahoma size=2&gt;http://msdn2.microsoft.com/en-US/library/ms229976(VS.80).aspx&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&lt;STRONG&gt;Passing transaction ownership in a sequence of threads&lt;BR&gt;&lt;/STRONG&gt;Described at &lt;/FONT&gt;&lt;A href="http://pluralsight.com/blogs/jimjohn/archive/2006/01/01/17769.aspx" mce_href="http://pluralsight.com/blogs/jimjohn/archive/2006/01/01/17769.aspx"&gt;&lt;FONT face=Tahoma size=2&gt;http://pluralsight.com/blogs/jimjohn/archive/2006/01/01/17769.aspx&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Tahoma size=2&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&lt;STRONG&gt;Async Programming&lt;BR&gt;&lt;/STRONG&gt;This is the scenario described in &lt;A href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/518956.aspx"&gt;my previous post&lt;/A&gt; where the client asks asynchronously a service to do some work as part of the transaction, but doesn’t want/need to wait until the service completes the work. The code will look like the following in .Net:&lt;BR&gt;&lt;BR&gt;Client Code&lt;BR&gt;&lt;FONT face=Verdana color=#0000ff&gt;void MainFunction()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; using(TransactionScope ts = new TransactionScope())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // dtx is a member of the current class of type DependentTransaction&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // its lifetime needs to be at least until the ack from the service is received&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.dtx = Transaction.Current.DependentClone(DependentCloneOption.&lt;STRONG&gt;BlockCommitUntilComplete&lt;/STRONG&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AsyncDoTransfer(tx, AckFromDoTransfer);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ts.Complete();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;void AckFromDoTransfer()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.dtx.Complete();&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Server Code&lt;BR&gt;&lt;FONT face=Verdana color=#0000ff&gt;void AsyncDoTransfer(tx, AckFromDoTransfer)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DependentTransaction dtx = tx.DependentClone(DependentCloneOption. &lt;STRONG&gt;BlockCommitUntilComplete&lt;/STRONG&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AckFromDoTransfer(); // the client can Commit safely from now on since I have dtx created on the service side&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // the dependent clone auto-created by TransactionScope doesn’t help in this scenario because it rollbacks on early commit while we need a blocking clone&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; using(TransactionScope ts = new TransactionScope(tx))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // doing the work that takes a lot of time&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB1.OpenConnection();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB1.DoDebit(amount);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB2.OpenConnection();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DB2.DoCredit(amount);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ts.Complete();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// work if finished on the service so we can safely let the transaction continue&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtx.Complete();&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=572035" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/florinlazar/archive/tags/MSDTC/default.aspx">MSDTC</category><category domain="http://blogs.msdn.com/florinlazar/archive/tags/Transactions/default.aspx">Transactions</category><category domain="http://blogs.msdn.com/florinlazar/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/florinlazar/archive/tags/phase0/default.aspx">phase0</category><category domain="http://blogs.msdn.com/florinlazar/archive/tags/DependentTransaction/default.aspx">DependentTransaction</category></item></channel></rss>