Distributed Transaction using .NET

Any distributed application has a common requirement to use distributed transaction. So .NET provide facility to full-fill the requirement.

TransactionScope class (namespace System.Transactions) has accomplish that task.

In previously I knew that without "Distributed Transaction Coordinator" service run, distributed transaction is not possible. But if you stop that service, TransactionScope class work fine. So now that service dependency has removed. The followling i show code sample

namespace TestConsole
{

class Program
{
static void Main(string[] args)
{
TransactionController _controoler = new TransactionController();
_controoler.TestDistributedTransaction();
}

}//end of program


class TransactionController
{

string cnnStringDB = @"Data Source=db; Database=Test_Habib; uid=sa; pwd=1;";

string cnnStringZahid = @"Data Source=Zahid\SqlExpress; Initial Catalog=MwMD; trusted_connection=true;";

string sql = "INSERT INTO Test_Transaction(ID, Name) VALUES (4, 'Bona');";


public void TestDistributedTransaction()
{
SqlCommand cmd = new SqlCommand(sql);

int result = -1;

using (System.Transactions.TransactionScope sc = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required))
{

try
{
SqlConnection con1 = new SqlConnection(cnnStringZahid);
con1.Open();
SqlCommand cmd1 = new SqlCommand(sql, con1);
result = cmd1.ExecuteNonQuery();
con1.Close();

using (System.Transactions.TransactionScope sc2 = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Suppress))
{
SqlConnection con2 = new SqlConnection(cnnStringDB);
con2.Open();
SqlCommand cmd2 = new SqlCommand(sql, con2);
result = cmd2.ExecuteNonQuery();
}

// RPC call to another appdomain using serialization.
sc.Complete();
}
catch (Exception ex)
{
sc.Dispose();
}
}
}

}//end class

}//end namespace

In above sample System.Transactions.TransactionScopeOption enum is important.
It has 3 values

i) Required
ii)RequiredNew
iii)Suppress

In the second block i use System.Transactions.TransactionScopeOption.Suppress. Otherwise it will through exception. TransactionScope.Complete() method commit all transaction. If not call this method explicitly then all transaction will be rollbacked automatically.


The following code sample you can use for multi-threaded distributed transaction handling.

        private static void WorkerThread(object transaction)
{
DependentTransaction dTx = (DependentTransaction)transaction;

using (TransactionScope ts = new TransactionScope(dTx))
{
//Perform transactional work here.
//Call complete on the transaction scope
ts.Complete();
}

//Call complete on the dependent transaction
dTx.Complete();
}

Thanks.