6

現在のプロジェクトでは、アプリケーションのデータ層として ADO.NET Entity Framework を使用しています。データベースで行う作業が多いため、トランザクションで実行する必要があるタスクがいくつかあります。これらのタスクを囲むためにTransactionScopeを使用しています。

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    // Do something...
    transactionScope.Complete();
}

問題は、 TransactionScopeを使用するとすぐに例外が発生することです。

System.Data.EntityException: 基になるプロバイダーが Open で失敗しました。---> System.Transactions.TransactionManagerCommunicationException: 基になるトランザクション マネージャーとの通信に失敗しました。---> System.Runtime.InteropServices.COMException (0x80004005): COM コンポーネントの呼び出しからエラー HRESULT E_FAIL が返されました。

このエラーは、MSDTC (Microsoft Distributed Transaction Coordinator) で何らかの処理を行う必要があるようです。MSDTC のセキュリティ構成を変更すると、別の例外がスローされます。

System.Data.EntityException: 基になるプロバイダーが Open で失敗しました。---> System.Transactions.TransactionManagerCommunicationException: 分散トランザクション マネージャー (MSDTC) のネットワーク アクセスが無効になっています。コンポーネント サービス管理ツールを使用して、MSDTC のセキュリティ構成でネットワーク アクセスに対して DTC を有効にしてください。

ただし、MSDTC が構成されていると、TransactionScopeによってエラーが発生します。誰かがここで何がうまくいかないのか知っていますか?

4

8 に答える 8

7

デフォルトでは、MSDTC のネットワーク アクセスは無効になっています。それを機能させるには、に行く必要があります

コントロール パネル -> 管理ツール -> コンポーネント サービス -> コンポーネント サービス -> コンピューティング -> マイ コンピューター -> 右クリック -> プロパティ -> MSDTC -> セキュリティ構成

ネットワーク DTC アクセス、インバウンドを許可、アウトバウンドを許可のチェックボックスをオンにします。環境に応じて認証を選択する必要があります。また、分散トランザクションをデバッグするためのDTCPingツールを確認することもできます。ショートカットを作成するには、レジストリを変更する必要がある場合があります。

HKLM\Software\Policies\Microsoft\Windows NT\RPCRestrictRemoteClients=0 HKLM\Software\Policies\Microsoft\Windows NT\RPCEnableAuthEpResolution=1

すべてを稼働させるために。

于 2009-10-23T08:27:30.293 に答える
3

はい、抑制を使用して動作します。これは、アンビエント トランザクションを抑制または無視し、新しいローカル トランザクションを作成するように指示しているためです。トランザクションはローカルであるため、分散トランザクションではないため、MSDTC を使用していませんが、おそらく Suppress を使用するべきではなく、代わりに Required を使用する必要があります。

于 2011-03-11T21:01:22.340 に答える
0

これは、コード ブロックに入ったときに現在有効である可能性のあるすべてのトランザクションを抑制していることを意味します。そのため、外側の「周囲の」トランザクションがロールバックすることを決定した場合、コードが行う更新はロールバックされません。

于 2009-12-15T01:39:29.097 に答える
0

「トランザクションでEntity Frameworkを使用している場合、Entity Frameworkは各データベース呼び出しで接続を自動的に開いたり閉じたりします。したがって、トランザクションを使用する場合、トランザクションを複数の接続に分散しようとします。これはMSDTCに昇格します。」

トランザクションで呼び出し先クラスまたは関数にデータベース コンテキストを渡すことができます。

多分これがあなたの答えです: MSSQL エラー '基礎となるプロバイダーが Open で失敗しました'

于 2013-05-29T03:05:45.690 に答える
0

トランザクションの抑制は、失敗する可能性のあるコードを実行したいが、その失敗のためにトランザクションを中止したくない場合に役立ちます。

自問する必要がある質問は次のとおりです。transactionScope で複数の永続的なリソースにアクセスしていますか? つまり、複数の DB への接続を開いていますか?

複数の永続リソースにアクセスするとトランザクションが DTC にエスカレートされるため、これは重要な質問です。

単一フェーズの通知をサポートする少なくとも 2 つの永続的なリソースが、トランザクションに登録されます。たとえば、単一の接続を登録しても、トランザクションは昇格されません。ただし、データベースへの 2 番目の接続を開いてデータベースを参加させると、System.Transactions インフラストラクチャは、それがトランザクション内の 2 番目の永続的なリソースであることを検出し、MSDTC トランザクションにエスカレートします。 出典: MSDN

その場合は、トランザクションスコープを正しくネストすることで問題を解決できます。例:

//Create rootScope
using(TransactionScope rootScope = new TransactionScope()) 
{ 
    using(TransactionScope scope2 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB1
         ...

         //Complete this ambient transaction
         scope2.Complete();
    } 

    using(TransactionScope scope3 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB2
         ...

         //Complete this ambient transaction
         scope3.Complete();
    } 

    //Complete rootScope
    //The whole transaction will only be committed if you call 
    //Complete on the rootScope
    rootScope.Complete();

}

MSDNで、TransactionScopes、ネストの仕組みなどの詳細を見つけることができます。

この答えが将来人々に役立つことを願っています。

于 2015-03-13T08:15:43.637 に答える
0

これは、私たち自身の同様の問題を解決するために使用した記事です。

MSDTC に関する問題のトラブルシューティング

これは基本的にNikolay R の回答への補遺です。彼は、記事に記載されている提案のいくつかをすでに取り上げました。

注: この記事は Biztalk ドキュメントの一部ですが、MSDTC を使用するあらゆるものに適用できます。

于 2010-02-23T21:11:04.837 に答える
0

Distributed Transaction Coordinator サービスが開始されていない場合、Entity フレームワークはデータベースに接続できません。分散トランザクション コーディネーターを開いて開始する

サービス -> 分散トランザクション コーディネーター

于 2015-05-12T07:11:04.990 に答える
-3

うーん、 TransactionScopeOptionを "Suppress" に変更するとうまくいくようです:

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
{
    ...
}

誰もが理由を知っていますか?

于 2009-10-23T10:35:45.627 に答える