web-dev-qa-db-ja.com

C#でTransactionScopeを使用する方法

TransactionScopeを使用しようとしていますが、以下の例外が発生し続けます。
重要な場合、アプリはデータベースとは別のマシンで実行されています。 SQL Server 2005を使用しています。

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

using (TransactionScope tsTransScope = new TransactionScope())
{
    //Do stuff here
    tsTransScope.Complete();
}

編集

フィードバックに基づいていくつかの変更を行いました。今、私はこのエラーを得ています:

「エラーHRESULT E_FAILがCOMコンポーネントの呼び出しから返されました。」
「基礎となるトランザクションマネージャとの通信に失敗しました。」

解決策私は受け入れられた答えが私が得ていた最初の問題を修正したと思います。 2番目のエラーはEntity Frameworkに固有のようです。別の質問を投稿します。

これがクライアントのプロパティです:
クライアントhttp://www.portnine.com/data/images/Misc/client.jpg

これがサーバーのプロパティです:
サーバーhttp://www.portnine.com/data/images/Misc/server.jpg

37
NotDan

この Microsoft TechNet Article の説明に従って、ネットワークDTCアクセスを有効にする必要があります。この変更は、データベースサーバーとアプリケーションサーバーの両方で行う必要がある場合があります。多くの場合、DTCは既にデータベースサーバーで有効になっているため、最初にアプリケーションサーバーを確認します。

以下は、「リモート管理を許可する」オプションを除いて使用するスクリーンショットです。 Security Configuration Screenshot

現在発生しているHRESULT E_Failの問題は発生していませんが、この記事 XP SP2とトランザクション に関する興味深い提案がありました。

注意する必要があるもう1つの構成設定(これは珍しいシナリオであると考えています)は、RestrictRemoteClientsレジストリキーです。このキーの値が2(RPC_RESTRICT_REMOTE_CLIENT_HIGH)に設定されている場合、MSDTCネットワークトランザクションは正しく機能しません。 MSDTCは、RPC_RESTRICT_REMOTE_CLIENT_NONE(0)およびRPC_RESTRICT_REMOTE_CLIENT_DEFAULT(1)の値のみをサポートします。 RestrictRemoteClientsの詳細については、 http://www.Microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection12812112012 を参照してください。

最後に、特定の問題ではありませんが、TransactionScopeクラスの使用に関して注意すべき非常に重要なことは、デフォルトの設定では Transaction Isolation Level of Serializable を使用することです。 Serializableは分離レベルの最も制限的なものであり、率直に言って、デフォルトとして選択されたのは驚くべきことです。このレベルのロックが必要ない場合は、TransactionScopeをインスタンス化するときに分離レベルを制限の少ないオプション(ReadCommitted)に設定することを強くお勧めします。

var scopeOptions = new TransactionOptions();
scopeOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
scopeOptions.Timeout = TimeSpan.MaxValue;

using (var scope = new TransactionScope(TransactionScopeOption.Required,
    scopeOptions))
{
    // your code here
}
33
ahsteele

コントロールパネル-管理ツール-コンポーネントサービス-マイコンピュータのプロパティ-[MSDTC]タブ-[セキュリティ構成]タブ-ネットワークDTCアクセス(オン)/リモートクライアントを許可(オン)/受信を許可(オン)/送信を許可(オン)/ TIPトランザクションを有効にする(チェック済み)

コンピュータを再起動します。

3
Otávio Décio

使用しているバックエンドによっては、TransactionScopeで分散トランザクションマネージャーを有効にする必要があることがよくあります。詳細は このMSDNブログ です。

また、複数のリソースを使用する場合は、DTCが必要になることがあります。状況によっては、DTCを有効にする必要がある場合があります。または、SQL Server 2005を使用していて、軽量トランザクションで何ができるかに固執していることを確認してください。

2
Reed Copsey

コンポーネントサービス管理ツールを使用して、MSDTCのセキュリティ構成でネットワークアクセス用のDTCを有効にする必要があります。

1
Mia Clarke

SQL Server 2000を使用している場合は、System.Transactions.TransactionScopeを指定すると、すべてのトランザクションが分散トランザクションに昇格され、MS分散トランザクションコーディネーターが実行されている必要があります。

これを修正するには、MSDTCサービスを開始するか、SQL Server 2005にアップグレードするか、コードプロジェクトソリューションのようなものを実装します。 http://www.codeproject.com/KB/database/typed_dataset_transaction.aspx

私はこれを行う必要はありませんでしたが、DTCのネットワークセキュリティ設定を構成するためのOcdecioの回答も確認する必要があります。

0
Neil Barnwell

データベースサーバーとアプリケーションが実行されているサーバーの両方に対してネットワークDTCアクセスを有効にする必要があります。

また、ファイアウォールによって接続がブロックされないことを確認する必要があります。データベースサーバーからアプリケーションマシンへの接続が開始されるため、アプリケーションマシンのファイアウォール例外のリストにMSDTCを追加することも同様に重要です。

統合テストの実行で同じ問題が発生しました。

私はこれについて質問を投稿しました ここ

しかし、最終的に私はそれを回避する方法を見つけました。ただし、量産コードでそれを行うことはお勧めしません。私はテストのコンテキスト内でそれをやっていました。

0
Joseph