<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pearl Tech &#187; MSDTC</title>
	<atom:link href="http://blog.pearltechnology.com/tag/msdtc/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.pearltechnology.com</link>
	<description></description>
	<lastBuildDate>Thu, 05 Jan 2012 14:47:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Use of TransactionScope in .NET</title>
		<link>http://blog.pearltechnology.com/use-of-transactionscope-in-net-2/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/use-of-transactionscope-in-net-2/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 12:53:50 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[MSDTC]]></category>
		<category><![CDATA[TransactionScope]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=79</guid>
		<description><![CDATA[In one of the projects I’m currently working on, I have to handle multiple SQL operations in one transaction, so if anything goes wrong in a particular operation, things done in previous operations can be rolled back automatically.  This can be done by using Transaction in a Stored Procedure directly, but you might lose some [...]]]></description>
			<content:encoded><![CDATA[<p>In one of the projects I’m currently working on, I have to handle multiple SQL operations in one transaction, so if anything goes wrong in a particular operation, things done in previous operations can be rolled back automatically.  This can be done by using Transaction in a Stored Procedure directly, but you might lose some flexibility that way.  For example, when you want to insert an object with multiple children in database, it’s not easy to pass an array or a list of items (children object) to the Stored Procedure.  So, I considered using TransactionScope provided by .NET to handle this.</p>
<p>In order to get away from code being escalated to MSDTC (Microsoft Distributed Transaction Coordinator), I decided to use single SqlConnection per TransactionScope.  Also, to maximize code reusability, we ended up with the following development pattern.  For simplicity reason, error handling is not added in the example below.</p>
<pre style="font-family:Courier New;line-height:14px"><span style="color:blue">public</span> <span style="color:blue">static</span> <span style="color:blue">void</span> CreateOrder(<span style="color:#006080">Order</span> myOrder)
{
    <span style="color:blue">using</span> (<span style="color:#006080">TransactionScope</span> scope =
            <span style="color:blue">new</span> <span style="color:#006080">TransactionScope</span>(<span style="color:#006080">TransactionScopeOption</span>.RequiresNew))
    {
        <span style="color:blue">using</span> (<span style="color:#006080">SqlConnection</span> cn = <span style="color:#006080">DB</span>.GetConnection())
        {
            cn.Open();
            <span style="color:#006080">SqlCommand</span> cmd = <span style="color:blue">new</span> <span style="color:#006080">SqlCommand</span>();
            cmd.Connection = cn;

            InsertOrderTransaction(myOrder, cmd);
        }
        scope.Complete();
    }
}

<span style="color:blue">internal</span> <span style="color:blue">static</span> <span style="color:blue">void</span> InsertOrderTransaction(<span style="color:#006080">Order</span> myOrder, <span style="color:#006080">SqlCommand</span> cmd)
{
    cmd.CommandText = "dbo.spCOrder";
    cmd.<span style="color:#006080">CommandType</span> = <span style="color:#006080">CommandType</span>.StoredProcedure;

    cmd.Parameters.Clear();
    cmd.Parameters.AddWithValue("@CustomerID", myOrder.CustomerID);
    <span style="color:green">// ...</span>

    myOrder.ID = <span style="color:#006080">Convert</span>.ToInt64(cmd.ExecuteScalar());

    InsertOrderTransactionPostProcessing(myOrder, cmd);
}</pre>
<p>As you can see, the method InsertOrderTransaction takes the Order object and a SqlCommand instance. It assumes that the SqlConnection has been established for the SqlCommand in the calling method. It doesn’t care if the SqlCommand needs to be executed within a transaction or not. It simply executes a SQL statement or a Stored Procedure. In its calling method CreateOrder, it defines the TransactionScope and defines and opens a SqlConnection. It can call multiple transactional methods (in this case InsertTransaction) and keep them all in one transaction. However, you don’t have to define a TranscationScope in the calling method if you are not dealing with multiple SQL operations. You can also add pre-processing and post-processing functions if needed.</p>
<pre style="font-family:Courier New;line-height:14px"><span style="color:blue">internal</span> <span style="color:blue">static</span> <span style="color:blue">void</span> InsertOrderTransactionPostProcessing(<span style="color:#006080">Order</span> myOrder, <span style="color:#006080">SqlCommand</span> cmd)
{
    <span style="color: #0000ff">if</span> (myOrder.OrderItems != <span style="color:blue">null</span>)
    {
        <span style="color: #0000ff">foreach </span>(<span style="color:#006080">OrderItem</span> myItem<span style="color:blue"> in </span>myOrder.OrderItems)
        {
            myItem.OrderID = myOrder.ID;
            InsertOrderItemTransaction(myItem, cmd);
        }
    }
}

<span style="color:blue">internal</span> <span style="color:blue">static</span> <span style="color:blue">void</span> InsertOrderItemTransaction(<span style="color:#006080">OrderItem</span> myItem, <span style="color:#006080">SqlCommand</span> cmd)
{
    cmd.CommandText = "dbo.spCOrderItem";
    cmd.<span style="color:#006080">CommandType</span> = <span style="color:#006080">CommandType</span>.StoredProcedure;

    cmd.Parameters.Clear();
    cmd.Parameters.AddWithValue("@ItemID", myItem.ItemID);
    <span style="color:green">// ...</span>
    myItem.OrderItemID = <span style="color:#006080">Convert</span>.ToInt64(cmd.ExecuteScalar());
}</pre>
<p>One thing you have to be aware of is that TransactionScope may not be a good choice if these operations take too long to complete. The reason is obvious. Transaction may result in temporary locking on certain objects (such as tables) in your database. If the transaction needs 5 minutes to complete, it may lock a table for that long and your users may be unable to access data in the table for that long. If anything goes wrong at the very last second in the transaction, it may take another 5 minutes for the database to roll back previous operations in this transaction, and make the table inaccessible to your users for even longer. So in cases like this, one transaction may need to be broken into multiple segments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/use-of-transactionscope-in-net-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

