In an earlier article, I explained that you could use the System.Transaction feature DependentTransaction to ensure that a transaction commit was held until all the activity for the transaction had completed. One scenario that was in our minds was its use in a multithreaded environment. A commenter asked for an example showing how this could be done. Below is a simple example:
using
System;
using System.Threading;
using System.Transactions;
namespace
MultiThread
{
class Program
{
public static void ThreadProc(object o)
{
DependentTransaction dtx = (DependentTransaction) o;
using (TransactionScope s = new TransactionScope(dtx))
{
// Wait 5 seconds just to make sure this thread
// completes after the main one.
//
Thread.Sleep(5000);
Console.WriteLine("About to complete the worker thread's transaction scope");
s.Complete();
}
Console.WriteLine("Completing the dependent clone");
dtx.Complete();
}
static void Main(string[] args)
{
DependentTransaction dtx;
Thread newThread = new Thread (new ParameterizedThreadStart(Program.ThreadProc));
using (TransactionScope s = new TransactionScope())
{
dtx = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
newThread.Start(dtx);
Console.WriteLine("About to complete the main thread");
s.Complete();
}
Console.WriteLine("Transaction Completed");
}
}
}
When you run it you get the following output:
About to complete the main thread
About to complete the worker thread's transaction scope
Completing the dependent clone
Transaction Completed
What is happening is that a DependentTransaction marked to “block commit until it is complete“ is created in the main thread, and then handed off ot the created thread. The main thread then immediately begins transaction commitment, which stalls awaiting the completion of the DependentTransaction (if you're really interested in internals, this uses what MSDTC called “Phase 0”). In the worker thread, the transaction continues, and eventually signals completion of the DependentTransaction. As soon as that happens, the commit processing started on the original thread wakes up and finishes.
Posted
May 01 2005, 07:51 AM
by
jim-johnson