トランザクションの開始と終了をログ出力

トランザクションの開始と終了は基本的にフレームワーク側で自動化するのがいいと思います。フレームワークで処理する場合はログは好きに出せますが、アプリでどうしても制御したいという場合に直接TransactionScopeを実行されるとログに出力されないのが不便ですね。TransactionScopeを完全に隠蔽化してしまうのはやりすぎな気がするなぁと思っていたところ、生成だけをユーティリティクラスでお願いすればよさそうだと思いつきました。

ユーティリティクラス


public static class TxUtil
{
public static TransactionScope Begin()
{
var txScope = new TransactionScope();
var tx = Transaction.Current;
var info = tx.TransactionInformation;
Console.WriteLine("Begin {0} {1}", info.LocalIdentifier, info.Status);
tx.TransactionCompleted += OnTransactionCompleted;
return txScope;
}

private static void OnTransactionCompleted(object sender, TransactionEventArgs e)
{
var tx = e.Transaction;
var info = tx.TransactionInformation;
Console.WriteLine("End {0} {1}", info.LocalIdentifier, info.Status);
tx.TransactionCompleted -= OnTransactionCompleted;
}
}

テストコード


[TestMethod]
public void TestLogTxCommit()
{
using (var txScope = TxUtil.Begin())
{
Console.WriteLine("in progress.");
txScope.Complete();
}
}

[TestMethod]
public void TestLogTxRollback()
{
using (var txScope = TxUtil.Begin())
{
Console.WriteLine("in progress.");
}
}

TestLogTxCommit()の実行結果

Begin dc2fa2d3-dd8c-42e3-892a-49876f80fed9:1 Active
in progress.
End dc2fa2d3-dd8c-42e3-892a-49876f80fed9:1 Committed

TestLogTxRollback()の実行結果

Begin 1149cec8-9e1b-4562-b81b-4922789d5ff5:1 Active
in progress.
End 1149cec8-9e1b-4562-b81b-4922789d5ff5:1 Aborted

この例ではConsole出力していますが、ほんとうは適当なロギングフレームワークを使うのがいいですね。
あとはTransactionScopeはいろんなコンストラクタを持っているのでそれに対応したメソッドがユーティリティクラスに必要です。