葛藤プログラマの一日

2006-09-27

System.Transactions による分散トランザクション

.NETFramework2.0から追加された機能です。これがあれば、別々のDBサーバーの情報を1つのトランザクションで更新できるようになります。いままでは、1つのトランザクションで複数のDBサーバーの情報を更新しようとしたら、リンクサーバーとか使わなければいけませんでしたが、これでだいぶ楽になります。


テストしたソースはこんな感じ…

SqlConnection con1 = null;
SqlConnection con2 = null;
try {
con1 = new SqlConnection("connectionString");
SqlCommand cmd1 = con1.CreateCommand();
cmd1.CommandText = "commandText ";

con2 = new SqlConnection("connectionString");
SqlCommand cmd2 = con2.CreateCommand();
cmd2.CommandText = "commandText";

using ( TransactionScope ts = new TransactionScope() ) {
con2.Open();
cmd2.ExecuteNonQuery();

con1.Open();
cmd1.ExecuteNonQuery();

ts.Complete();
}
} finally {
if ( con1 != null )
con1.Close();
if ( con2 != null )
con2.Close();
}


おおっ、すばらしい。きちんとトランザクションが1つになっています。
今回は、commandText については、トランザクションを使用したストアドプロシージャを指定しました。System.Transactions を使うことで、ストアドプロシージャで指定したトランザクションは無視されるようです。今まで使っていたストアドプロシージャがそのまま使えるという点で、安心です。


最後に、環境整備ではまった点

1.クライアント、サーバーそれぞれに、MSDTCが必要!
WindowsXPは標準で入っているようですが、サーバーは別途インストールする必要があります。





  1. [Windows コンポーネントの追加と削除] をクリックします。
  2. [アプリケーション サーバー] ―. [ネットワーク DTC アクセスの有効化] を追加
  3. 分散トランザクション コーディネータ サービスを停止し、再び開始します。
  4. Microsoft SQL Server、および分散トランザクションと連携するその他のリソース マネージャ サービス (Microsoft メッセージ キューなど) をすべて停止し、再び開始します。
    (要は、再起動が良いでしょう(^^;)
2.「Distributed Transaction Coordinator」サービスが開始されていること!
これ、MSDTCのサービスです。


3.エラー別の対処法

【エラー内容】
"分散トランザクション マネージャ (MSDTC) のネットワーク アクセスは
無効になっています。 コンポーネント サービス管理ツールを使用して、
MSDTC のセキュリティ構成でネットワーク アクセスの DTC を有効にして
ください。"

http://support.microsoft.com/kb/839279

サーバー、クライアント、共に必要な設定。

「対処手順 」
(1) dcomcnfg.exe (または、[管理ツール] – [コンポーネントサービス ]を起動)

(2) コンポーネントサービスを展開して、[マイコンピュータ]のプロパティ を選択















(3) [MSDTC]タブ – [セキュリティ構成]ボタン を押す


















(4) Windows XP, Windows Server 2003R2 の場合


  1. 次の項目にチェックを付ける
    ・[セキュリティ設定] - [ネットワーク DTC アクセス]

  2. ・[セキュリティ設定] - [トランザクション マネージャ通信] - [受信を許可する]

  3. ・[セキュリティ設定] - [トランザクション マネージャ通信] - [送信を許可する]

  4. ・[セキュリティ設定] - [トランザクション マネージャ通信] - [認証を必要としない]


(5) Windows Server 2003 の場合
次の項目にチェックを付ける
・[セキュリティ設定] - [ネットワーク DTC アクセス]

・[セキュリティ設定] - [ネットワーク DTC アクセス] - [ネットワーク トランザクション]

・[セキュリティ設定] - [ネットワーク DTC アクセス] - [ネットワーク クライアント]

(6) OSに関係なく、
[DTC ログオン アカウント] – [アカウント] が「NT AUTHORITY\NeworkService」になっていることを確認。なっていなければ、アカウントを変更する。




【エラー内容】
"基本トランザクション マネージャとの通信が失敗しました。"
http://support.microsoft.com/kb/839279

「対処手順」

Windowsファイアーウォールの例外に以下の2つを追加
 「%windir%\system32\msdtc.exe」
 「[ポート番号] 135 、[TCP]」



【エラー内容】
"パートナー トランザクション マネージャにより、リモート トランザクションまたはネットワーク トランザクションのサポートが無効にされました。 (HRESULT からの例外: 0x8004D025) "
http://support.microsoft.com/?scid=kb;ja;817064&spid=3208&sid=62


DBサーバー側の設定変更

「対処手順」

  1. [Windows コンポーネントの追加と削除] をクリックします。
  2. [アプリケーション サーバー] ―. [ネットワーク DTC アクセスの有効化] を追加
  3. 分散トランザクション コーディネータ サービスを停止し、再び開始します。
  4. Microsoft SQL Server、および分散トランザクションと連携するその他のリソース マネージャ サービス (Microsoft メッセージ キューなど) をすべて停止し、再び開始します。

    最後のSQLServer再起動を忘れやすいので注意!ちなみに、WindowsServer2003R2の場合は、再起動が要りません。