トランザクションスコープにより、暗黙的な分散トランザクションを使用できます。トランザクションスコープを使用する場合、分散トランザクション中のデータ操作は、Windowsのサービスである、Microsoft Distributed Transaction Coordinator(以降、MSDTCと略します)により制御されます。
MSDTCの起動
トランザクションスコープ(System.Transactions 名前空間)を使用する場合、MSDTCサービスを起動しておく必要があります。
Windowsのサービスの一覧で、“Distributed Transaction Coordinator”サービスが開始状態であることを確認してください。
トランザクションスコープを使用したアプリケーションの作成方法を説明します。
[アプリケーション作成の流れ]
//1. System.Transactions名前空間導入 using System.Transactions; //2. トランザクション スコープの開始 using (TransactionScope ts = new TransactionScope()) { SymfowareConnection con = new SymfowareConnection(); //3. スコープにトランザクションの登録 con.ConnectionString = "DATA SOURCE=127.0.0.1;PORT=26551;" + "INITIAL CATALOG=TEST;USER ID=USER01;PASSWORD=PASS01;ENLIST=TRUE"; con.Open(); //4. Closeメソッドの呼び出し con.Close(); //5. Complete()メソッドの呼び出し ts.Complete(); //6. トランザクションスコープの終了 } //7. 終了作業の同期 System.Threading.Thread.Sleep(3000);
アプリケーションにSystem.Transactions名前空間導入
トランザクションスコープの開始
新しい TransactionScopeオブジェクトを作成すると、トランザクションスコープが開始されます。usingステートメントを使用してスコープを作成することを推奨します。
TransactionScopeオブジェクトを新規作成する場合、下記の情報を設定できます。詳細は、Microsoft社のMSDNライブラリを参照してください。
入れ子になったスコープとルートスコープの関係設定(既定値:Required)
トランザクションスコープのタイムアウトの設定(既定値:60秒)
トランザクションスコープの分離レベルの設定(既定値:Serializable)
スコープにトランザクションを登録
以下の2つの条件を満たす場合、当該コネクションはトランザクションスコープに登録され、当該コネクションのトランザクションがトランザクションスコープマネージャより管理されます。
当該コネクションの接続文字列のEnlistキーワードの値として、trueが設定されている
当該コネクションがトランザクションスコープ内で、SymfowareConnectionのOpen()メソッドを呼び出す
SymfowareConnectionのCloseメソッドの呼び出し
コネクションを切断する場合、占用した資源を解放するために、当該コネクションのClose()メソッドを呼び出してください。
TransactionScopeオブジェクトのComplete()メソッドの呼び出し
トランザクションスコープ内ですべての操作を完了したら、TransactionScopeオブジェクトのComplete メソッドを一度だけ呼び出す必要があります。呼び出さない場合、トランザクションがデフォルトで強制終了します。
トランザクションスコープの終了
トランザクションのコミットおよびロールバックは、トランザクションスコープブロックを終了する際に、当該TransactionScopeオブジェクトのDisposeメソッドを呼び出すことによって実行されます。
アプリケーションとトランザクションスコープの終了作業の同期
トランザクションスコープの終了作業は、トランザクションスコープマネージャにより、アプリケーションのスレッドとは異なる、新しいスレッドを発行して実行されています。下記の動作を保証するために、アプリケーションで手動同期処理が必要です。
トランザクションスコープの終了作業が完了するまでの時間を確保する
トランザクションスコープブロック後の作業と並行することを避ける
手動同期処理では、トランザクションスコープが終了後、数秒間経過してから、アプリケーションをブロックするようにしてください。
サンプルプログラムについては、“A.2.13 TransactionScopeクラスを利用した分散トランザクション制御”または“A.3.13 TransactionScopeクラスを利用した分散トランザクション制御”を参照してください。
トランザクションスコープを使用したアプリケーションを作成する場合の注意事項を説明します。
コネクションの接続文字列のEnlistキーワードの値に、falseが設定された場合、当該コネクションは、トランザクションスコープに登録できません。
トランザクションスコープのタイムアウトの最大許容時間の初期値は10分です。最大許容時間を10分以上に設定するには、.NET FrameworkのMachine.configファイルに下記を設定してください。
例:最大許容時間を15分に設定
<configuration> <system.transactions> <machineSettings maxTimeout="00:15:00" /> </system.transactions> </configuration>
1つのトランザクションスコープ内でのコネクション数とスレッド数に対しては、以下の制限があります。
コネクション数は、システム用の動作環境ファイルのMAX_CONNECT_TCPに指定した接続可能な最大コネクション数の1/2の値を超えないでください。
超えた場合、トランザクションスコープの終了時に、接続可能な最大コネクション数の限界を超えて、以下のエラーが発生します。
[Symfoware] JYP9229E システムコールにおいてエラーが発生し,サーバとの通信が切断されました.
“コネクション数 × スレッド数”の値は、32を超えないでください。
超えた場合、MSDTCが管理できるブランチ数の許容範囲を超えて、以下のエラーが発生します。また、トランザクションスコープを強制的にロールバックして、トランザクションが終了します。
[Symfoware] JYP1021E システムコールにおいてエラーが発生しました.分散トランザクションマネージャでは、これ以上トランザクションへの永続参加を受け入れません。”
“コネクション数 × スレッド数”の値は、コネクションプールのMaxPoolSizeまたはmaxpooledconnectionsの値を超えないでください。
超えた場合、一部のコネクションが接続できなくなり、以下のエラーが発生します。
[Symfoware] JYP9224E Connection Timeoutの制限時間を超えました.
トランザクションスコープ内で、マルチスレッドまたはパラレルを利用する場合、スレッド間に、セッション単位の一時表のデータは共有できません。
トランザクションスコープを利用する場合、以下のメソッドの機能範囲は、同じ接続文字列を持つすべてのSymfowareConnectionオブジェクトに対して有効となります。
SymfowareConnection.ChangeDataBase
SymfowareConnection.SetRole
トランザクションスコープ以外の場合は、コネクション単位に有効です。
トランザクションスコープを終了する前に、トランザクションスコープ内で接続されているコネクションを切断する必要があります。もし、切断されないコネクションがある場合、TransactionAbortedException異常が発生します。
トランザクションスコープを利用する際に、以下の場合に、アプリケーションが排他待ちになる可能性があります。
同じトランザクションスコープ内で、接続文字列が違うコネクションが同じ資源を更新する場合。
同じトランザクションスコープ内で、マルチスレッドの場合、スレッド間で同じ、または違うコネクションが同じ資源を更新する場合。
排他待ちが発生する場合、トランザクションスコープのタイムアウト機能を利用して、トランザクションスコープをロールバックできます。行単位の排他を使用していて、トランザクションスコープのタイムアウト機能を利用してもタイムアウトが有効とならない場合、チューニングパラメタのWAIT_TIMEやTRAN_TIME_LIMITを併用して排他待ちを解除してください。
参照
トランザクションスコープ制御の詳細は、Microsoft社のMSDNライブラリの“トランザクション スコープを使用した暗黙的なトランザクションの実装”を参照してください。
トランザクションスコープを利用したアプリケーションの運用時に、異常が発生した場合のトランザクションの状態判定および対処方法を説明します。
異常の種類
トランザクションスコープ内の処理が、指定されたトランザクションスコープのタイムアウト時間内に終了していない場合、タイムアウト異常が発生します。
トランザクションスコープに登録された複数なトランザクションの一貫性を保証するために、2フェーズコミット制御を行います。1フェーズと2フェーズの間に異常が発生すると、トランザクションの結果として不定の状態(インダウト状態)となり、トランザクションで占用した資源がインダウト閉塞することになります。
インダウト閉塞になると、閉塞が解除されるまで資源はアクセス禁止状態になります。禁止状態の資源をアクセスすると異常が返却されます。この時に返却された異常をインダウト状態異常と呼びます。
トランザクションの状態判定および対処方法
異常の種類ごとに、トランザクションの状態判定および対処方法を説明します。
タイムアウト異常が発生した場合、トランザクションマネージャはTransactionAbortedException をスローします。その結果、トランザクションスコープに登録されたすべての分散トランザクションの実行が中止となり、ロールバックされます。
タイムアウト以外に、以下の場合にも、TransactionAbortedExceptionが発生する可能性があります。
トランザクションスコープが終了する時に、トランザクションスコープ内に接続中のコネクションが存在する
リソースの競合に関するデッドロックが発生した
インダウトログ状態異常の判定方法を説明します。
サーバ側がLinuxまたはSolarisの場合、インダウトログファイルを利用することでインダウト状態を判定できます。
参照
インダウトログファイルについては、“RDB運用ガイド”を参照してください。
rdblogコマンドを利用して、インダウトログファイルの状態を確認できます。
インダウトログ状態がactiveの場合、インダウトが発生していることを示します。
参照
インダウトログファイルの状態の表示方法については、“クラスタ導入運用ガイド”の“インダウトログファイルの状態表示”を参照してください。
以下のいずれかの方法で、インダウト状態を確認できます。
RDBREPORTで指定したメッセージログファイルを確認し、以下のエラーメッセージがある場合、インダウトが発生していることを示します。
qdg13529u:XA配下のトランザクションがインダウト状態になりました
RDB システムがダウンし、RDBシステムを再起動するときに、以下のメッセージが出力された場合、インダウトが発生していることを示します。
qdg12210w:XA配下のインダウトなトランザクションが存在します
rdbxarcvコマンドを利用して、インダウトトランザクションを解決できます。
参照
rdbxarcvコマンドの指定方法の詳細については、“コマンドリファレンス”を参照してください。