マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

  • TransactionScopeクラスは、2相コミットを実現するための.NET 2.0のAPIであり、
    内部的には、トランザクション マネージャ(TM)・リソース マネージャ(RM)であるMS-DTCを使用している。
  • MS-DTCだけでなく、WS-Transactionなどで使われる予定だったが、最近、これらの技術適用は非常に少なくなった。

詳細

経緯

  • ASP.NET 1.xでは、

動作確認用のサンプル プログラム(ASP.NET)

2相コミットの動作確認用サンプル プログラムを用いて、TransactionScopeクラスの利用方法を説明する。

SQL Server

下記は、SQL Server用のデータ アクセス ライブラリである、
SqlClient?を利用した場合のサンプル コード。

private void Two_Phase_Commit(bool flag)
{
  TransactionOptions txopt = new TransactionOptions();
  txopt.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
        
  //txopt.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead;
  //txopt.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
  //txopt.IsolationLevel = System.Transactions.IsolationLevel.Snapshot;        
  //txopt.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
        
  using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, txopt))
  {
    using (SqlConnection con = new SqlConnection(@"Data Source=AAA;Initial Catalog=northwind;User ID=xxx;Password=xxx;"))
    {
      using (SqlCommand com = new SqlCommand())
      {
        com.Connection = con;
        com.CommandText = "insert into table1(bbb) values('データ')";
        try
        {
          con.Open();
          com.ExecuteNonQuery();
        }
        finally
        {
          con.Close();
        }
      }
    }
    using (SqlConnection con = new SqlConnection(@"Data Source=BBB;Initial Catalog=northwind;User ID=xxx;Password=xxx;"))
    {
      using (SqlCommand com = new SqlCommand())
      {
        com.Connection = con;
        com.CommandText = "insert into table1(bbb) values('データ')";
        try
        {
          con.Open();
          com.ExecuteNonQuery();
        }
        finally
        {
          con.Close();
        }
      }
    }

    if (flag) // flag変数はコミット、ロールバックのテストのための実装
    {
      scope.Complete();
    }
    else{ }
  }
}
  • 分離レベルの選択が可能。Snapshot分離レベルは、SQLServer2005以降でサポートされる。
  • using (TransactionScope scopeのUsingステートメント範囲内のTransactionScopeオブジェクトの破棄までがトランザクション範囲となる
    (Usingステートメント コードブロックは、範囲外に出る際に、自動的にオブジェクトのDispose()メソッドを呼び出す仕様になっている)。
  • このため、Usingステートメントを使用しない実装をする際は手動でTransactionScope.Dispose()メソッドを呼び出す必要がある。
  • 最後に、TransactionScope.Complete()メソッドを呼び出し、上記のプログラム中の2つの接続が持つトランザクションは分散トランザクションとして2相コミットされる。
  • TransactionScope.Complete()メソッドを呼び出さない状態でTransactionScopeオブジェクトが破棄された(Usingステートメントは、範囲外に出た)場合は、分散トランザクションは、ロールバックされる。

Oracle

  • 下記は、Oracle用のデータ アクセス ライブラリである、System.Data.OracleClient?、ODP.NETを利用した場合のサンプル コードである。
  • 実装を見てわかるとおり、ADO.NETの仕様に合わせ、APIのインターフェイスも共通化されているため、他のDBMSのデータプロバイダも含め、実装に大きな違いは無い。
private void Two_Phase_Commit(bool flag)
{
  TransactionOptions txopt = new TransactionOptions();
  txopt.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;

  //txopt.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead;
  //txopt.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
  //txopt.IsolationLevel = System.Transactions.IsolationLevel.Snapshot;
  //txopt.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;

  using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, txopt))
  {
    using (OracleConnection con = new OracleConnection(@"User Id=xxx;Password=xxx;Data Source=AAA/orcl;"))
    {
      using (OracleCommand com = new OracleCommand())
      {
        com.Connection = con;
        com.CommandText = "insert into table1(aaa, bbb) values(1, 'データ')";
        try
        {
          con.Open();
          com.ExecuteNonQuery();
        }
        finally
        {
          con.Close();
        }
      }
    }
    using (OracleConnection con = new OracleConnection(@"User Id=xxx;Password=xxx;Data Source=BBB/orcl;"))
    {
      using (OracleCommand com = new OracleCommand())
      {
        com.Connection = con;
        com.CommandText = "insert into table1(aaa, bbb) values(1, 'データ')";
        try
        {
          con.Open();
          com.ExecuteNonQuery();
        }
      finally
      {
        con.Close();
        }
      }
    }

    if (flag) // flag変数はコミット、ロールバックのテストのための実装
    {
      scope.Complete();
    }
    else{ }
  }
}

Tags: :インフラストラクチャ, :Windows, :データアクセス, :ADO.NET


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-12-17 (火) 16:47:37 (1582d)