<?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</title><link>http://blogs.msdn.com/b/florinlazar/</link><description>Make it simple, robust and scalable</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>System.Transactions and Allow Inbound/Outbound DTC Settings</title><link>http://blogs.msdn.com/b/florinlazar/archive/2009/09/23/9898808.aspx</link><pubDate>Thu, 24 Sep 2009 08:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9898808</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=9898808</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2009/09/23/9898808.aspx#comments</comments><description>If you do distributed transactions across the network, you know about Allow Inbound and Allow Outbound security settings for DTC (available by running dcomcnfg or by opening Component Services). 
 The help describes these settings as: 
 
 Allow Inbound...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2009/09/23/9898808.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9898808" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/promotable+transactions+System-Transactions+DTC+Inbound+Outbound/">promotable transactions System.Transactions DTC Inbound Outbound</category></item><item><title>Intro for Microsoft Azure .Net Service Bus</title><link>http://blogs.msdn.com/b/florinlazar/archive/2009/04/02/9530050.aspx</link><pubDate>Fri, 03 Apr 2009 05:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9530050</guid><dc:creator>florinlazar</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=9530050</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2009/04/02/9530050.aspx#comments</comments><description>Clemens Vasters gives a great introduction to Microsoft Azure .Net Service Bus and its 4 feature areas: Naming, Registry, Connectivity, and Eventing. Find it at http://vasters.com/clemensv/PermaLink,guid,92d78bee-2cfd-4a29-95ab-c5abb9b905e7.aspx...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2009/04/02/9530050.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9530050" width="1" height="1"&gt;</description></item><item><title>Atbroker.exe application error - CTRL-ALT-END in a remote session</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/11/25/9143089.aspx</link><pubDate>Wed, 26 Nov 2008 04:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9143089</guid><dc:creator>florinlazar</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=9143089</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/11/25/9143089.aspx#comments</comments><description>I use remote desktop daily. The Atbroker.exe application error followed by black screen seemed to be gone for a while. Now it is back. The only solution that I know of and which works most of the times is "CTRL-ALT-END" (the equivalent of “CTRL-ALT-DEL...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/11/25/9143089.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9143089" width="1" height="1"&gt;</description></item><item><title>When not to use transactions and where you can't use transactions</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/05/08/8475058.aspx</link><pubDate>Fri, 09 May 2008 01:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8475058</guid><dc:creator>florinlazar</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8475058</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/05/08/8475058.aspx#comments</comments><description>Transactions are great when everyone plays in. You group a set of activities together under a transaction and you start executing them. If anything bad happens along the way or something doesn't go as planned, invoke rollback and all is taking care of...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/05/08/8475058.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8475058" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/transactions+compensation/">transactions compensation</category></item><item><title>MSDTC and COM+ Configuration Tool in Vista</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/05/07/8467420.aspx</link><pubDate>Thu, 08 May 2008 01:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8467420</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8467420</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/05/07/8467420.aspx#comments</comments><description>To access the MSDTC and COM+ configuration tool in Windows Vista, also known as Component Services MMC, you have the following options: 
 1. Run “dcomcnfg” 
 2. Or run: %SystemRoot%\System32\comexp.msc 
 3. Or if you prefer, you can add a shortcut...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/05/07/8467420.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8467420" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/MSDTC+Configuration/">MSDTC Configuration</category></item><item><title>Exception Handling without catch(Exception)</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/05/06/8465197.aspx</link><pubDate>Wed, 07 May 2008 09:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8465197</guid><dc:creator>florinlazar</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8465197</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/05/06/8465197.aspx#comments</comments><description>The design guidelines for exception handling are quite clear on avoiding “catch all” and/or avoiding catching exceptions you can’t handle. But there are cases when you really need to know if the try block completed successfully or not, and possibly take...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/05/06/8465197.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8465197" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/exceptions/">exceptions</category></item><item><title>Working with CMD and Long Path Names</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/05/06/8463808.aspx</link><pubDate>Tue, 06 May 2008 22:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8463808</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8463808</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/05/06/8463808.aspx#comments</comments><description>I like using the command prompt for a lot of things and working with long (or very long) path names is something that is common these days. 
 Fortunately, you can customize cmd by using "prompt". Do a “prompt /?” in a command window to see all the options...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/05/06/8463808.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8463808" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/cmd/">cmd</category></item><item><title>How to Use System.Data with System.Transactions and Maintain Atomicity and Data Consistency</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/05/05/8460156.aspx</link><pubDate>Mon, 05 May 2008 13:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8460156</guid><dc:creator>florinlazar</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8460156</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/05/05/8460156.aspx#comments</comments><description>The Bug 
 I call it a bug. Initially I was persuaded to believe it was a feature; later I was "convinced" that it is now a matter of app compat and it can't be changed anymore. 
 
 Let’s look at the following code: 
 
 SqlConnection connection1 ...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/05/05/8460156.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8460156" width="1" height="1"&gt;</description></item><item><title>Limitation of TransactionScope (and using)</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/05/05/8459994.aspx</link><pubDate>Mon, 05 May 2008 11:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8459994</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8459994</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/05/05/8459994.aspx#comments</comments><description>If you read the documentation for TransactionScope , you will find: "If no exception occurs within the transaction scope […], then the transaction in which the scope participates is allowed to proceed. If an exception does occur within the transaction...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/05/05/8459994.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8459994" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/TransactionScope/">TransactionScope</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/using/">using</category></item><item><title>Avoiding Transaction Promotion with Multiple Connections - Improvements in System.Data and SQL Server 2008</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/05/02/8452486.aspx</link><pubDate>Sat, 03 May 2008 02:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8452486</guid><dc:creator>florinlazar</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8452486</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/05/02/8452486.aspx#comments</comments><description>Great news! The new updates added to System.Data and SQL Server 2008 finally allow multiple Open/Close connections to the same SQL Server without promoting the transaction to MSDTC. 
 This was by far the most requested feature for the System.Transactions...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/05/02/8452486.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8452486" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/System-Data/">System.Data</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Lightweight+Transactions/">Lightweight Transactions</category></item><item><title>A Simpler TransactionScope</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/03/24/8334137.aspx</link><pubDate>Mon, 24 Mar 2008 22:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8334137</guid><dc:creator>florinlazar</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=8334137</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/03/24/8334137.aspx#comments</comments><description>In .Net 3.5 I can write a transactional code block as follows: transacted(()=&amp;gt; 
{
 using (SqlConnection connection = new SqlConnection(connectionString))
 {
 connection.Open();

 SqlCommand command1 = new SqlCommand(commandString1, connection...(&lt;a href="http://blogs.msdn.com/b/florinlazar/archive/2008/03/24/8334137.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8334137" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/TransactionScope/">TransactionScope</category></item><item><title>Flowing or propagating transactions in .Net</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/02/20/flowing-or-propagating-transactions-in-net-blog-entry-under-construction.aspx</link><pubDate>Wed, 20 Feb 2008 21:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7821919</guid><dc:creator>florinlazar</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=7821919</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/02/20/flowing-or-propagating-transactions-in-net-blog-entry-under-construction.aspx#comments</comments><description>&lt;P&gt;System.Transactions transactions are bounded to the appdomain. Which means that if you make in-appdomain calls from inside a TransactionScope, those calls will share the transaction. This also means that if you need to make a call outside the current appdomain, or outside the process, you will need to "flow" the transaction. &lt;/P&gt;
&lt;P&gt;To flow a System.Transactions transaction, there are a few options:&lt;/P&gt;
&lt;P&gt;a. if you are using&amp;nbsp;serialization&lt;BR&gt;&amp;nbsp; &lt;PRE class=csharpcode&gt;//sender code
using(TransactionScope ts = new TransactionScope())
{
  RemoteCallUsingSerialization(Transaction.Current, other parameter); // this is the call to other appdomain/process
  // notice I added a new parameter of type System.Transactions.Transaction  

  ts.Complete();
}

//destination code
void RemoteCallUsingSerialization(System.Transactions.Transaction tx, other parameter)
{
  using(TransactionScope ts2 = new TransactionsScope(tx))
  {
   // access transactional resourses like a database; this code will execute as part of the same transaction
   ts2.Complete();
  }
}
&lt;/PRE&gt;
&lt;P&gt;b. if you are not using&amp;nbsp;serialization&lt;BR&gt;&amp;nbsp; &lt;PRE class=csharpcode&gt;//sender code
using(TransactionScope ts = new TransactionScope())
{  
  RemoteCall(TransactionInterop.GetTransmitterPropagationToken(Transaction.Current), other parameter); // this is the remote call
  // notice I added a new parameter of type byte[]  

  ts.Complete();
}

//destination code
void RemoteCall(byte[] tx, other parameter)
{
  using(TransactionScope ts2 = new TransactionsScope(TransactionInterop.GetTransactionFromTransmitterPropagationToken(tx)))
  {
   // access transactional resourses like a database;
   // this code will execute as part of the same transaction
   ts2.Complete();
  }
}
&lt;/PRE&gt;
&lt;P&gt;c. if .Net 3.0 or higher is an option, you can use WCF and its support for transactions using attributes: &lt;A href="http://msdn2.microsoft.com/en-us/library/aa347993.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa347993.aspx"&gt;http://msdn2.microsoft.com/en-us/library/aa347993.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Remark: When the transaction is flown outside the current appdomain, it will get upgraded to a distributed transaction (or MSDTC transaction).&lt;/P&gt;
&lt;P&gt;If you are not using .Net, see &lt;A href="http://blogs.msdn.com/florinlazar/archive/2004/10/02/236965.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2004/10/02/236965.aspx"&gt;http://blogs.msdn.com/florinlazar/archive/2004/10/02/236965.aspx&lt;/A&gt; for propagating transactions in C++.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7821919" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/flow+propagate+transactions+System-Transactions/">flow propagate transactions System.Transactions</category></item><item><title>TIP is now deprecated</title><link>http://blogs.msdn.com/b/florinlazar/archive/2008/01/22/tip-is-now-deprecated.aspx</link><pubDate>Wed, 23 Jan 2008 04:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7203676</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=7203676</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2008/01/22/tip-is-now-deprecated.aspx#comments</comments><description>TIP is getting deprecated - see the note at &lt;A href="http://msdn2.microsoft.com/en-us/library/ms679484(VS.85).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms679484(VS.85).aspx&lt;/A&gt;&lt;BR&gt;If the native OleTx protocol used by MSDTC and System.Transactions is not friendly enough for your firewall, you should consider the WS-AtomicTransactions protocol provided through Windows Communication Foundation in .Net Framework 3.0 and higher: &lt;A href="http://msdn2.microsoft.com/en-us/library/ms730266.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms730266.aspx&lt;/A&gt;&lt;BR&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7203676" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/TIP+WS_2D00_AT/">TIP WS-AT</category></item><item><title>MSDN Magazine Article on Transactional File System</title><link>http://blogs.msdn.com/b/florinlazar/archive/2007/07/11/msdn-magazine-article-on-transactional-file-system.aspx</link><pubDate>Wed, 11 Jul 2007 21:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3818063</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=3818063</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2007/07/11/msdn-magazine-article-on-transactional-file-system.aspx#comments</comments><description>&lt;P&gt;Jason Olson describes the Transactional NTFS and how you can take advantage of it in your applications: &lt;A href="http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx"&gt;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx&lt;/A&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3818063" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Transactional+NTFS/">Transactional NTFS</category></item><item><title>WCF in Romania</title><link>http://blogs.msdn.com/b/florinlazar/archive/2007/05/02/wcf-in-romania.aspx</link><pubDate>Thu, 03 May 2007 09:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2388526</guid><dc:creator>florinlazar</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=2388526</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2007/05/02/wcf-in-romania.aspx#comments</comments><description>&lt;P&gt;These days I'm in Romania with a tour at 3 universities (in Bucharest, Cluj and Iasi)&amp;nbsp;talking about Windows Communication Foundation, distributed systems and web services. &lt;A class="" title="Adi Oltean" href="http://blogs.msdn.com/adioltean/" mce_href="http://blogs.msdn.com/adioltean/"&gt;Adi Oltean&lt;/A&gt; is also talking about storage technologies in Windows.&lt;/P&gt;
&lt;P&gt;So far the seminars were received really well and&amp;nbsp;we made a lot of friends. I'm really&amp;nbsp;pleased to be able to contribute to the adoption of WCF and to demonstrate the amazing value and power of WCF with its productivity, interoperability and extensibility features.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;More details at &lt;A href="http://reg.studentclub.ro/RegisterForEvent.aspx?idEveniment=55"&gt;http://reg.studentclub.ro/RegisterForEvent.aspx?idEveniment=55&lt;/A&gt;&amp;nbsp;(in romanian).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;I would like to thank &lt;A class="" title="Todi Pruteanu" href="http://weblogs.studentclub.ro/todi" mce_href="http://weblogs.studentclub.ro/todi"&gt;Todi Pruteanu&lt;/A&gt; for organizing these events.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2388526" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Romania+WCF/">Romania WCF</category></item><item><title>"Orcas" March 07 CTP: Support for OASIS WS-AT 1.1 and WS-Coord 1.1</title><link>http://blogs.msdn.com/b/florinlazar/archive/2007/03/07/orcas-march-07-ctp-support-for-oasis-ws-at-1-1-and-ws-coord-1-1.aspx</link><pubDate>Thu, 08 Mar 2007 03:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1832238</guid><dc:creator>florinlazar</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=1832238</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2007/03/07/orcas-march-07-ctp-support-for-oasis-ws-at-1-1-and-ws-coord-1-1.aspx#comments</comments><description>&lt;P&gt;In the &lt;A class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=B533619A-0008-4DD6-9ED1-47D482683C78&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=B533619A-0008-4DD6-9ED1-47D482683C78&amp;amp;displaylang=en"&gt;"Orcas" March 2007 CTP for Visual Studio and .Net&lt;/A&gt;, Windows Communication Foundation brings support for OASIS specifications &lt;A class="" href="http://docs.oasis-open.org/ws-tx/wsat/2006/06" mce_href="http://docs.oasis-open.org/ws-tx/wsat/2006/06"&gt;WS-AtomicTransaction 1.1&lt;/A&gt; and &lt;A class="" href="http://docs.oasis-open.org/ws-tx/wscoor/2006/06" mce_href="http://docs.oasis-open.org/ws-tx/wscoor/2006/06"&gt;WS-Coordination 1.1&lt;/A&gt;. WCF will have side-by-side support with the 1.0 versions of these specs.&lt;/P&gt;
&lt;P&gt;To use the new version of WS-AT, you can specify the new WS2007HttpBinding, or, if you already use the NetTcpBinding, you can set the TransactionProtocol to WSAtomicTransactions11.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1832238" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Orcas+WCF+WS_2D00_AT/">Orcas WCF WS-AT</category></item><item><title>Allowing Transactions into Your Component: "Do you really want that?"</title><link>http://blogs.msdn.com/b/florinlazar/archive/2007/03/07/allowing-transactions-into-your-component-do-you-really-want-that.aspx</link><pubDate>Wed, 07 Mar 2007 15:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1827227</guid><dc:creator>florinlazar</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=1827227</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2007/03/07/allowing-transactions-into-your-component-do-you-really-want-that.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;Supporting transactions&amp;nbsp;is part of your component contract. If you shipped a component yesterday that exposed MyComp.DoWork to the public, and today you want to add transactional support to your component, you shouldn't use the same method MyComp.DoWork and make it transactions aware. Not unless you want to break your customers (see &lt;A href="http://blogs.msdn.com/florinlazar/archive/2005/04/19/409834.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2005/04/19/409834.aspx"&gt;http://blogs.msdn.com/florinlazar/archive/2005/04/19/409834.aspx&lt;/A&gt; for details on how you can break existing apps). Instead you should publish a new method, MyComp.TransactedDoWork, that you document it as being transactions aware, i.e. it will participate in the ambient transaction if one is available.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The purpose of this post is not about TransactedDoWork, but rather about a new method, MyComp.DoMoreWork, that you want to add to your v2. Let's assume that in this method, you write an entry into a file, call a webservice and update two databases. Since you learned about System.Transactions, you are using TransactionScope to make the updates to the two databases. And since most of the samples use the default constructor for TransactionScope, you are probably doing it the same way:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;PRE class=csharpcode&gt;using (TransactionScope ts = new TransactionScope())
{
    // open connection to db1
    // update db1
    // close connection to db1
    // open connection to db2
    // update db2
    // close connection to db2
    
    ts.Complete();
}
&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;All appears to be good and so you ship MyComp v2. After a while, you start getting reports from your customers saying that sometimes, MyComp.DoMoreWork doesn't work properly: they see the update to the file, they see the webservice being called but the updates to databases are missing. What is going on?&lt;/P&gt;
&lt;P mce_keep="true"&gt;Well, the default constructor for TransactionScope uses TransactionScopeOption.Required, which enlists in the ambient transaction if one exists. Thus, if your customers are using transactions and they call MyComp.DoMoreWork, and if the transaction aborts, part of the work done by DoMoreWork is going to be rollbacked!! But that wasn't what you intended.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The best practice is to always "protect" your outermost TransactionScopes in our component from enlisting in the ambient transaction by using a non-default constructor, &amp;nbsp;TransactionScope(TransactionScopeOption.RequiresNew) or TransactionScope(TransactionScopeOption.Suppress), depending on your particular scenario. Of course, if you want the transaction to flow inside the component you can use the default constructor, but that should be a conscious decision.&lt;/P&gt;
&lt;P&gt;Given that the TransactionScope is usually hidden into the call stack of your component method, for instance:&lt;/P&gt;&lt;PRE class=csharpcode&gt;void MyComp.DoMoreWork
{
    internalDoTheRealMoreWork(); // the first TransactionScope shows up inside internalDoTheRealMoreWork
}
&lt;/PRE&gt;
&lt;P&gt;The best way to deal with unwanted transactions is to start your public interface methods with a non-default TransactionScope:&lt;/P&gt;&lt;PRE class=csharpcode&gt;void MyComp.DoMoreWork
{
    using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Suppress))
    {
        internalDoTheRealMoreWork();		
        ts.Complete();
    }
}
&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;The reason why TransactionScope default is Required is to allow easy creation of imbricated or nested TransactionScopes (not to be confused with "nested transactions"):&lt;/P&gt;&lt;PRE class=csharpcode&gt;void internalDoTheRealMoreWork()
{
    using (TransactionScope ts = new TransactionScope())
    {
        // work
        myOtherInternalWork();
        ts.Complete();
    }
}
void myOtherInternalWork();
{
    using (TransactionScope ts = new TransactionScope())
    {
        // do other work
        ts.Complete();
    }	
}
&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;With the default constructor you write less code and the transactions "flows" nicely from method to method in the call stack. You are supposed to use the non-default constructors for TransactionScope, when you want to make a decision not to allow the ambient transaction inside your component or method. One of those cases is in the public interface methods.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Next time you write a public method, always ask yourself - "do I want to let a transaction in or not?" - if the answer is no, then start your public method with a non-default TransactionScope. And remember to document your method's behavior with regards to transactions.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1827227" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/TransactionScope+contract/">TransactionScope contract</category></item><item><title>Supporting Promotable Transactions and Phase 0</title><link>http://blogs.msdn.com/b/florinlazar/archive/2007/02/10/supporting-promotable-transactions-and-phase-0.aspx</link><pubDate>Sat, 10 Feb 2007 16:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1643248</guid><dc:creator>florinlazar</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=1643248</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2007/02/10/supporting-promotable-transactions-and-phase-0.aspx#comments</comments><description>If you are providing support for promotable transactions for your resource manager using PSPE&amp;nbsp;then you need to remember to "support" Phase 0. 
&lt;P mce_keep="true"&gt;In general, a resource manager doesn't need to do anything special about Phase 0; this phase will be handled solely by the transaction manager. But, because in the case of promotable transactions using the PSPE mechanism, the resource manager acts as a special "transaction manager", your resource manager needs to be aware of Phase 0. Why? Because in this case, the resource manager "owns" the distributed transaction and System.Transaction will call Commit on the PSPE interface asking the resource manager to call Commit on the distributed transaction. The resource manager needs to be aware that even after it will call Commit on the distributed transaction it owns, there is a possibility that requests to enlist and do work as part of the same transaction are still possible, based on the Phase 0 rules. And these requests are supposed to be accepted. Don't worry, there will be no data corruption. MSDTC guarantees that Phase 0 happens before Phase 1 starts delivering its "prepare" messages. &lt;/P&gt;
&lt;P mce_keep="true"&gt;What exactly you need to do to ensure Phase 0 support? Let's create the list:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;when you receive the "commit" request through the PSPE interface, call Commit on the distributed transaction but do not start the commit process on your data yet; wait for the Prepare message on the distributed transaction from MSDTC before doing any work (this assumes you are enlisted with that transaction - you should be!); in other words, when you receive the IPromotableSinglePhaseNotification::SinglePhaseCommit simply "pass" along the Commit to the distributed trasaction you own and don't do anything else&lt;/LI&gt;
&lt;LI&gt;don't get confused by the name of IPromotableSinglePhaseNotification::SinglePhaseCommit; it is not the same as the classic single phase commit from MSDTC; there might be phase 0 enlistments out there that might enlist other durable resource managers in the transaction, and thus a 2-Phase-Commit might be necessary&lt;/LI&gt;
&lt;LI&gt;even after calling Commit on the distributed transaction, you should continue to accept new connections and work on the same transaction; don't worry, phase 1 didn't start yet, these are just phase 0 enlistments "flushing" their data to durable stores&lt;/LI&gt;
&lt;LI&gt;once you received the "prepare" message from MSDTC on the distributed transaction, only then you should start your normal 2PC operation&lt;/LI&gt;
&lt;LI&gt;if any new request is received on the same transaction after "prepare" was received from MSDTC, you should deny it as you do in any 2PC scenario after phase 1 started&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;Sounds like a lot of steps, but in reality, this can be said in a short summary: "when you receive IPromotableSinglePhaseNotification::SinglePhaseCommit, pass along the Commit to the distributed transaction you own and behave like it didn't happen :), i.e. accept new connection requests in the same transaction until MSDTC delivers you the "prepare" message.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Of course, if Promote was never called, then there isn't any distributed transaction involved and thus you can proceed with commiting the work when IPromotableSinglePhaseNotification::SinglePhaseCommit is called.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Related posts: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Phase 0: &lt;A href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/msdtc-the-magic-of-phase-zero-phase0-or-when-using-2pc-transactions-is-not-enough.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2006/01/29/msdtc-the-magic-of-phase-zero-phase0-or-when-using-2pc-transactions-is-not-enough.aspx"&gt;http://blogs.msdn.com/florinlazar/archive/2006/01/29/msdtc-the-magic-of-phase-zero-phase0-or-when-using-2pc-transactions-is-not-enough.aspx&lt;/A&gt; and &lt;A href="http://blogs.msdn.com/florinlazar/archive/2006/04/09/572035.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2006/04/09/572035.aspx"&gt;http://blogs.msdn.com/florinlazar/archive/2006/04/09/572035.aspx&lt;/A&gt; &lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;PSPE:&amp;nbsp;&lt;A href="http://blogs.msdn.com/florinlazar/archive/2005/05/17/418595.aspx" mce_href="http://blogs.msdn.com/florinlazar/archive/2005/05/17/418595.aspx"&gt;http://blogs.msdn.com/florinlazar/archive/2005/05/17/418595.aspx&lt;/A&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;Thanks for supporting promotable transactions and Phase 0.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1643248" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/promotable+transactions/">promotable transactions</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/phase0/">phase0</category></item><item><title>When transaction promotion goes "bad"</title><link>http://blogs.msdn.com/b/florinlazar/archive/2007/02/08/when-transaction-promotion-goes-bad.aspx</link><pubDate>Thu, 08 Feb 2007 14:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1626594</guid><dc:creator>florinlazar</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=1626594</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2007/02/08/when-transaction-promotion-goes-bad.aspx#comments</comments><description>&lt;P&gt;We already know the benefits of promotable transactions. They are all about performance, being very fast and lightweight.&lt;/P&gt;
&lt;P&gt;But then you get into situations where you know for sure that you are going to talk to a second resource manager, so you know you will get to a distributed transaction anyway. Or, the resource managers out there that support promotable transactions might have limitations when you put them into edge cases. But you really want to use that edge case and it doesn't work.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Well, one solution is to "turn off" promotion and force a distributed transaction from the beginning such that all the resource managers involved will follow the classic route of enlisting in the transaction. We don't actually provide a flag today in System.Transactions to "turn off" promotable transactions, but you can achieve it by forcing the transaction to be a distributed transaction before you open any resource manager connection.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The way you do it in code is by calling:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TransactionInterop.GetTransmitterPropagationToken(tx); &lt;/P&gt;
&lt;P&gt;Where tx is the transaction you want to promote.&lt;/P&gt;
&lt;P&gt;If you are using TrasactionScope similar to:&lt;/P&gt;&lt;PRE class=csharpcode&gt;using(TransactionScope ts = new TransactionScope())
{
    connection.Open();
    // do the work on the first connection
    connection2.Open();
    // do the rest of the work
    ts.Complete();
}&lt;/PRE&gt;Then the code with the workaround should be: &lt;PRE class=csharpcode&gt;using(TransactionScope ts = new TransactionScope();)
{
    TransactionInterop.GetTransmitterPropagationToken(Transaction.Current);
    connection.Open();
    // do the work on the first connection
    connection2.Open();
    // do the rest of the work
    ts.Complete();
}&lt;/PRE&gt;
&lt;P&gt;With time, resource managers will get better. But today, you might find this &amp;lt;trick&amp;gt; useful.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1626594" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/promotable+transactions/">promotable transactions</category></item><item><title>Comments for 90 days only</title><link>http://blogs.msdn.com/b/florinlazar/archive/2006/10/03/comments-for-90-days-only.aspx</link><pubDate>Wed, 04 Oct 2006 04:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:788345</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=788345</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2006/10/03/comments-for-90-days-only.aspx#comments</comments><description>&lt;P&gt;I'm getting way too much spam these days. I wanted to keep the comments open for ever so I can get your feedback at any time you wanted to send it to me. Unfortunately spam is consuming my time so I decided to limit the lifetime for comments to 90 days starting from the day of the post.&lt;/P&gt;
&lt;P mce_keep="true"&gt;If you want to send me feedback, you can use &lt;A href="http://blogs.msdn.com/florinlazar/contact.aspx" mce_href="http://blogs.msdn.com/florinlazar/contact.aspx"&gt;http://blogs.msdn.com/florinlazar/contact.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;If you have a question related to transactions, you can post it to our transactions forum at &lt;A href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=388&amp;amp;SiteID=1" mce_href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=388&amp;amp;SiteID=1"&gt;http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=388&amp;amp;SiteID=1&lt;/A&gt; where I'm the moderator.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Thanks for your understanding.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=788345" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Transactions/">Transactions</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/feedback/">feedback</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/forum/">forum</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/comments/">comments</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/contact/">contact</category></item><item><title>Phase0 in .Net System.Transactions</title><link>http://blogs.msdn.com/b/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><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=572035</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2006/04/09/phase0-in-net-system-transactions.aspx#comments</comments><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;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=572035" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/MSDTC/">MSDTC</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Transactions/">Transactions</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Programming/">Programming</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/phase0/">phase0</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/DependentTransaction/">DependentTransaction</category></item><item><title>Our Own Forum is Now Live! Please Join Us at the &amp;quot;Transactions Programming Forum&amp;quot;</title><link>http://blogs.msdn.com/b/florinlazar/archive/2006/03/10/our-own-forum-is-now-live-please-join-us-at-the-quot-transactions-programming-forum-quot.aspx</link><pubDate>Sat, 11 Mar 2006 02:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:549107</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=549107</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2006/03/10/our-own-forum-is-now-live-please-join-us-at-the-quot-transactions-programming-forum-quot.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;I'm really happy to announce that our own forum, dedicated to transactions in Windows and .Net is now live at &lt;/FONT&gt;&lt;A href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=388&amp;amp;SiteID=1"&gt;&lt;FONT face=Tahoma size=2&gt;http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=388&amp;amp;SiteID=1&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;The RSS feed for the forum is &lt;/FONT&gt;&lt;A href="http://forums.microsoft.com/MSDN/rss.aspx?ForumID=388&amp;amp;Mode=0&amp;amp;SiteID=1"&gt;&lt;FONT face=Tahoma size=2&gt;http://forums.microsoft.com/MSDN/rss.aspx?ForumID=388&amp;amp;Mode=0&amp;amp;SiteID=1&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;I hope that by having a forum that is dedicated to Transactions technologies we can build a better channel for our customers to get quick and accurate answers to their questions. We encourage everyone in the community to participate in this forum.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;I look forward to us working together to make this forum a valuable resource for Transactions discussions.&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=549107" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/MSDTC/">MSDTC</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Enterprise+Services/">Enterprise Services</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Transactions/">Transactions</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/COM_2B00_/">COM+</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Programming/">Programming</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Indigo/">Indigo</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/forum/">forum</category></item><item><title>Dedicated Site for Transactions on Microsoft.com</title><link>http://blogs.msdn.com/b/florinlazar/archive/2006/03/01/541177.aspx</link><pubDate>Wed, 01 Mar 2006 13:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:541177</guid><dc:creator>florinlazar</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=541177</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2006/03/01/541177.aspx#comments</comments><description>&lt;FONT face=Tahoma size=2&gt;In an effort to have a common place for all the transactions technologies we provide (and we started to have a good number of technologies that continues to grow), we have put together a webpage on Microsoft.com dedicated to transactions. The address is: &lt;/FONT&gt;&lt;A href="http://www.microsoft.com/windowsserver2003/appserver/transmgmt.mspx"&gt;&lt;FONT face=Tahoma size=2&gt;http://www.microsoft.com/windowsserver2003/appserver/transmgmt.mspx&lt;/FONT&gt;&lt;/A&gt;&lt;BR&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=541177" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/MSDTC/">MSDTC</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Transactions/">Transactions</category></item><item><title>MSDTC: The Magic of Phase Zero (Phase0) – Or – When Using 2PC Transactions Is Not Enough</title><link>http://blogs.msdn.com/b/florinlazar/archive/2006/01/29/msdtc-the-magic-of-phase-zero-phase0-or-when-using-2pc-transactions-is-not-enough.aspx</link><pubDate>Mon, 30 Jan 2006 01:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:518956</guid><dc:creator>florinlazar</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=518956</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2006/01/29/msdtc-the-magic-of-phase-zero-phase0-or-when-using-2pc-transactions-is-not-enough.aspx#comments</comments><description>&lt;P&gt;The most known technique of implementing distributed transaction is the "two-phase commit" (2PC).&amp;nbsp;Here is a quick summary of how this technique works:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Active phase: After the transaction is created and before the "commit" message is issued by the creator, the transaction is in the "active" state. During this phase, resource managers can "enlist" and become part of the transaction. When "commit" is issued, the transaction moves to Phase1.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Phase1 (preparing phase): in which the superior transaction manager (TM), after receiving the Commit message from the creator of the transaction, "asks" the enlisted resource managers or the subordinate transaction managers to "prepare" for commit; if all respond with a successful "prepared" answer then the transaction moves to Phase 2, otherwise the transaction is aborted&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Phase 2 (committing phase) the superior TM writes a durable log entry about the status of the transaction and then starts sending "commit" messages to all the resource managers and subordinate TMs part of the transaction. In the case of any type of error (communication, computer crash etc), the superior TM will continue to send the "commit" messages until a successful "committed" message is received from all the participants. When all the participants responded "committed", the log entry corresponding to the current transaction is removed from the log and the transaction ends.&lt;/P&gt;
&lt;P&gt;In addition to the "two-phase commit" technique, MSDTC supports another phase called &lt;STRONG&gt;Phase Zero (Phase0)&lt;/STRONG&gt; which occurs after the creator of the transaction calls Commit and before Phase1 starts. To participate in Phase0 you need to enlist as a Phase0 participant: &lt;A href="http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/transactionphase0enlistment_6j04.asp?frame=true" mce_href="http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/transactionphase0enlistment_6j04.asp?frame=true"&gt;http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/transactionphase0enlistment_6j04.asp?frame=true&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/pgdtc_dev_8ldf.asp?frame=true" mce_href="http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/pgdtc_dev_8ldf.asp?frame=true"&gt;http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/pgdtc_dev_8ldf.asp?frame=true&lt;/A&gt;. MSDTC will always start with Phase0 and remain there until all the Phase0 participants responded. &lt;/P&gt;
&lt;P&gt;The great benefit of Phase0 is that during this phase, any type of enlistment (including Phase0) in the transaction it is still allowed. Once the transaction moves to Phase1, the new enlistments will be denied. Since you can create a new Phase0 enlistment during Phase0, MSDTC executes this phase in waves. After "commit" is issued, the TM will first send "Phase0Request" messages (&lt;A href="http://msdn.microsoft.com/library/en-us/cossdk/htm/itransactionphase0notifyasync_8ywk.asp" mce_href="http://msdn.microsoft.com/library/en-us/cossdk/htm/itransactionphase0notifyasync_8ywk.asp"&gt;http://msdn.microsoft.com/library/en-us/cossdk/htm/itransactionphase0notifyasync_8ywk.asp&lt;/A&gt;) to all known Phase0 enlistments. If all of them successfully replied Phase0Done (&lt;A href="http://msdn.microsoft.com/library/en-us/cossdk/htm/itransactionphase0enlistmentasync_5pt1.asp" mce_href="http://msdn.microsoft.com/library/en-us/cossdk/htm/itransactionphase0enlistmentasync_5pt1.asp"&gt;http://msdn.microsoft.com/library/en-us/cossdk/htm/itransactionphase0enlistmentasync_5pt1.asp&lt;/A&gt;), the TM will look for new Phase0 enlistments that occurred meanwhile and it will start another Phase0 wave if any is found and so on. Phase0 will end when no other new Phase0 enlistment is found after a wave. After Phase0 ends, the transaction moves to Phase1.&lt;/P&gt;
&lt;P&gt;Phase0 allows the following three scenarios: caching resource managers, protection against "early" commits and "safe" propagation of transactions in async programming.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Caching Resource Managers&lt;/STRONG&gt;&lt;BR&gt;Using a Phase0 enlistment, a middle-tier component can delay the connection to the database(s) as long as possible, acting as a cache to the requests from the client and thus reducing network traffic and database locks. This works great for those scenarios in which the client does many changes to the same data before it finally decides to end and save the work. When the client "ends" the work, the transaction is committed, and the TM issues a Phase0Request to the caching component. Before replying Phase0Done, the component will open all the necessary connections to the databases that need to be involved and it will persist the final data. These databases will now be "durably" enlisted in the transaction. After Phase0Done is received, the TM will continue with the 2PC and commit the transaction. See also &lt;A href="http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/pgdtc_dev_0y2b.asp?frame=true" mce_href="http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/pgdtc_dev_0y2b.asp?frame=true"&gt;http://msdn.microsoft.com/library/?url=/library/en-us/cossdk/htm/pgdtc_dev_0y2b.asp?frame=true&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Protection Against "Early" Commits&lt;BR&gt;&lt;/STRONG&gt;In general, 2PC transactions help to ensure integrity of data during different types of system errors. Using Phase0 you can also protect from badly written software. &lt;/P&gt;
&lt;P&gt;Let me give an example: let's say a transaction is created on the client side and then propagated to a middle tier component that is asked to do work as part of that transaction. The work that this component needs to do involves two databases, DB1 and DB2, as follows:&lt;/P&gt;
&lt;P&gt;int DoTransfer(int amount, transaction tx)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;DB1.OpenConnection(tx);&lt;BR&gt;&amp;nbsp; DB1.DoDebit(amount);&lt;BR&gt;&amp;nbsp; DB2.OpenConnection(tx);&lt;BR&gt;&amp;nbsp; DB2.DoCredit(amount);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;The component is using the received transaction to communicate with the two databases to ensure the integrity of its data. Both Debit and Credit operations need to be successful or none should occur. This looks great until now. But what if the client doesn't wait for DoTransfer to finish and calls Commit right after the DB1.DoDebit returned and before DB2.OpenConnection started? A badly written client can do that, maybe the programmer wanted to use multi-threading but didn't quite get it right. What will happen is that the component is left with inconsistent data in the databases, a debit operation that occurred without a credit operation. There is nothing wrong with the transaction itself; from the point of view of the 2PC transaction, only one enlistment occurred and that one responded successfully to both "prepare" and "commit" phases. It is the application logic that is wrong here. &lt;/P&gt;
&lt;P&gt;Can you protect against this type of situation? Yes, you can. One way is to write bug-free code, but mistakes happen. If you don't own the client code, the problem is even harder. The best solution is to use a Phase0 enlistment and modify the middle tier code as follows:&lt;/P&gt;
&lt;P&gt;int DoTransfer(int amount, transaction tx)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;EnlistPhase0(tx); //Creates a Phase0 enlistment with the transactions&lt;/P&gt;
&lt;P&gt;&amp;nbsp;DB1.OpenConnection(tx);&lt;BR&gt;&amp;nbsp;DB1.DoDebit(amount);&lt;BR&gt;&amp;nbsp;DB2.OpenConnection(tx);&lt;BR&gt;&amp;nbsp;DB2.DoCredit(amount);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;SignalWorkCompletedToPhase0Enlistment(tx); // signals the Phase0 enlistment that the work was completed&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Your Phase0 enlistment should start with a "WorkCompleted" flag set to false. The method SignalWorkCompletedToPhase0Enlistment mentioned above will set this flag to true. If a Phase0Request is received and the flag is still false, it means that the Commit was issued before the DoTransfer finished its work. At this point, you have two options: &lt;BR&gt;- one option (the recommended one when "early commits are not expected) is to abort the transaction and log some error; if you own the client code you might want to catch and fix these "early" commits&lt;BR&gt;- the other option is to hold the Phase0Request, received while DoTransfer is still doing work, until the flag becomes true and only then let the transaction continue by replying with Phase0Done; use this option when you expect to receive "early" commits as part of your system logic and flow.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Asynchronous Programming&lt;/STRONG&gt;&lt;BR&gt;This is very similar to the early commits scenarios mentioned above, but this time, the early commits are "by design". One can encounter scenarios where a piece of the application starts a transaction and delegates the work asynchronously to other parts of the application (a different thread of execution, a remote location) and without waiting for a response continues with committing the transaction. In these scenarios, we will choose the second option from above, the one that blocks the commit until work is finished. The code is similar:&lt;BR&gt;&amp;nbsp;Client code:&lt;BR&gt;&amp;nbsp;&amp;nbsp;Transaction tx = StartTransaction();&lt;BR&gt;&amp;nbsp;&amp;nbsp;AsyncDoTransfer(tx); // like create a separate thread and let it do the transfer operation etc&lt;BR&gt;&amp;nbsp;&amp;nbsp;SomeOtherAsyncWork(tx);&lt;BR&gt;&amp;nbsp;&amp;nbsp;CommitTransaction(tx);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;Server code:&lt;BR&gt;&amp;nbsp;&amp;nbsp;// inside AsyncDoTransfer that receives the transaction from the client&lt;BR&gt;&amp;nbsp;&amp;nbsp;EnlistPhase0AndBlock(tx); // if we get a Phase0Request we will block and wait until SignalWorkCompletedToPhase0Enlistment is called and only then reply with Phase0Done&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp; DB1.OpenConnection(tx);&lt;BR&gt;&amp;nbsp; DB1.DoDebit(amount);&lt;BR&gt;&amp;nbsp; DB2.OpenConnection(tx);&lt;BR&gt;&amp;nbsp; DB2.DoCredit(amount);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; SignalWorkCompletedToPhase0Enlistment(tx); // signals the Phase0 enlistment that the work was completed&lt;BR&gt;&amp;nbsp;&amp;nbsp;return;&lt;/P&gt;
&lt;P&gt;Looks nice and safe... Well, there is a problem even with this code. What if, Commit is called even before we are able to enlist in Phase0 in the AsyncDoTransfer method? We can end up again with some inconsistent data. The solution is to create some sort of acknowledgment from the server to the client saying that at least it got to the phase0 enlistment: "hey client, I know I'm slow and I will do your requested work later but here is my ack that you can Commit your transaction safely any time from now on". To accomplish this we will have to use phase0 enlistments on both the client and server side as follows:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;Client Code:&lt;BR&gt;&amp;nbsp;&amp;nbsp;Void MainFunction()&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Transaction tx = StartTransaction();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EnlistPhase0AndBlock(tx); // if we get a Phase0Request we will block and wait until SignalWorkCompletedToPhase0Enlistment is called and only then reply with Phase0Done&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AsyncDoTransfer(tx, AckFromDoTransfer); // like sending an async message to a server and let it do the transfer operation etc&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CommitTransaction(tx);&amp;nbsp;&lt;BR&gt;&amp;nbsp; }&amp;nbsp; &lt;BR&gt;&amp;nbsp; void AckFromDoTransfer()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SignalWorkCompletedToPhase0Enlistment(tx); // signals the Phase0 enlistment that the work was completed&amp;nbsp;&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;Server Code:&lt;BR&gt;&amp;nbsp;&amp;nbsp;void AsyncDoTransfer(tx, AckFromDoTransfer)&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;EnlistPhase0AndBlock(tx); // if we get a Phase0Request we will block and wait until SignalWorkCompletedToPhase0Enlistment is called and only then reply with Phase0Done&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AckFromDoTransfer(); // the client can Commit safely the transaction from now, since I'm protected by phase 0&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // doing the work that takes a lot of time&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 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;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SignalWorkCompletedToPhase0Enlistment(tx); // signals the Phase0 enlistment that the work was completed&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;The phase0 enlistment on the client side will make sure that we keep the transaction in phase0 until we get all the acks from our servers. Look at this as a method to pass phase0 "ownership" from client to servers. &lt;/P&gt;
&lt;P&gt;All these work due to the "magic" of phase0 that allows "infinite" number of enlistments, until no new phase0 enlistments are being created and the existing ones replied with a successful Phase0Done. I compare the Phase0 enlistment to the AddRef method from the good old COM lifetime management. A Phase0 enlistment will call "AddRef" on the "active phase" of the transaction, while a Phase0Done will call "Release" on the counter. While the counter is higher than zero, the transaction will not be allowed to enter Phase1.&lt;BR&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=518956" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/MSDTC/">MSDTC</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Transactions/">Transactions</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Programming/">Programming</category><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/phase0/">phase0</category></item><item><title>Windows Communication Foundation (Indigo) Home Page</title><link>http://blogs.msdn.com/b/florinlazar/archive/2006/01/29/518953.aspx</link><pubDate>Mon, 30 Jan 2006 00:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:518953</guid><dc:creator>florinlazar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/florinlazar/rsscomments.aspx?WeblogPostID=518953</wfw:commentRss><comments>http://blogs.msdn.com/b/florinlazar/archive/2006/01/29/518953.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Windows Communication Foundation (Indigo) has its own page now at &lt;/FONT&gt;&lt;A href="http://windowscommunication.net/"&gt;&lt;FONT face=Tahoma size=2&gt;http://windowscommunication.net/&lt;/FONT&gt;&lt;/A&gt;&lt;BR&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=518953" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/florinlazar/archive/tags/Indigo/">Indigo</category></item></channel></rss>
