web-dev-qa-db-ja.com

TransactionScopeがEntity Frameworkで機能しないのはなぜですか?

以下のコードを参照してください。複数のエンティティコンテキストを初期化すると、2番目のコードのみのセットで次の例外が発生します。 2番目のセットをコメントアウトすると機能します。

{「基になるプロバイダーはオープンで失敗しました。」}

内部:{「基になるトランザクションマネージャーとの通信に失敗しました。」}

内部:{「COMコンポーネントへの呼び出しからエラーHRESULT E_FAILが返されました。」}

これはサンプルアプリであり、2つのコンテキストを続けて作成しても意味がないことを知っています。ただし、製品コードには同じTransactionScopeに複数のコンテキストを作成する理由があり、これは変更できません。

編集

これは、MS-DTCをセットアップしようとしている私の前の質問です。サーバーとクライアントの両方で有効になっているようです。正しく設定されているかどうかはわかりません。また、これを実行しようとしている理由の1つは、TransactionScope内の既存のコードがADO.NETとLinq 2 Sqlを使用していることです。これらにも同じトランザクションを使用してほしいと思います。 (それはおそらくクレイジーに聞こえますが、可能であればそれを機能させる必要があります)。

C#でTransactionScopeを使用するにはどうすればよいですか?

ソリューション

WindowsファイアウォールがMS-DTCへの接続をブロックしていました。

using(TransactionScope ts = new System.Transactions.TransactionScope())
        {
                using (DatabaseEntityModel o = new DatabaseEntityModel())
                {
                    var v = (from s in o.Advertiser select s).First();
                    v.AcceptableLength = 1;
                    o.SaveChanges();
                }

                //-> By commenting out this section, it works
                using (DatabaseEntityModel o = new DatabaseEntityModel())
                {
                    //Exception on this next line
                    var v = (from s1 in o.Advertiser select s1).First();                         v.AcceptableLength = 1;
                    o.SaveChanges();
                }
                //->

                ts.Complete();
        }
25
NotDan

MS-DTC(分散トランザクションコーディネーター)が何らかの理由で正しく機能していません。 MS-DTCは、複数のSQL接続を含む複数の異種リソースにわたるトランザクションの結果を調整するために使用されます。

何が起こっているかについての詳細は このリンク を見てください。

基本的に、MS-DTCが実行され、適切に機能していることを確認すれば、エンティティフレームワーク接続か他のタイプかに関係なく、2つのADO.NET接続の使用に問題はありません。

19
Steve Willcock

独自のEntityConnectionを管理し、このEntityConnectionをObjectContextに渡すことで、分散トランザクションの使用を回避できます。そうでなければこれらをチェックしてください。

http://forums.Microsoft.com/MSDN/ShowPost.aspx?PostID=580828&SiteID=1&mode=1http://forums.Microsoft.com/msdn/showpost.aspx? postid = 113669&siteid = 1&sb = 0&d = 1&at = 7&ft = 11&tf = 0&pageid = 1

EntityConnection conn = new EntityConnection(ConnectionString);

using (TransactionScope ts = new TransactionScope())
{
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
            var v = (from s in o.Advertiser select s).First();
            v.AcceptableLength = 1;
    }

    //-> By commenting out this section, it works
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
        //Exception on this next line
        var v = (from s1 in o.Advertiser select s1).First();
                v.AcceptableLength = 1;
    }
    //->

    ts.Complete();
}
19
dreadjr

ファイアウォールとサーバーの両方のファイアウォール例外にC:\ Windows\msdtc.exeを追加します。私はこれを行う前に、特定のポート番号と範囲を開放することを何回もやってみました。

5
burnside

昨日この問題をデバッグしている同僚と3時間過ごしたので、ここにこれを貼り付けておきます。これを取り巻くすべての答えは、これは常にファイアウォールの問題であると述べています。しかし、私たちの場合はそうではありませんでした。うまくいけば、これは他の誰かの痛みを免れるでしょう。

現在の状況は、現在Entity Frameworkに移行中です。つまり、単一のトランザクション内でnew SqlConnection(connectionString).Open()を使用して直接、およびEFデータコンテキストを使用して間接的に接続が開かれるコードの一部があります。

これは私たちのアプリケーションでしばらくうまく機能していましたが、本番環境で機能するコードをさかのぼってテストを開始すると、EFオブジェクトが初めて接続を試みたときに、テストランナーから実行されたコードがこのエラーをスローし続けましたデータベースへ変更後同じトランザクションで直接接続が行われました。

バグの原因は結局、接続文字列にApplication Name=引数を指定しない場合、Entity FrameworkがデフォルトでEntityFrameworkMUFのようなものを追加することにありました。これは、接続プールに2つの異なる接続があることを意味します。

  1. Application Name=引数なしで手動で開いたもの
  2. 自動的に生成される接尾辞Application Name=EntityFrameworkMUF

また、1つのトランザクション内で2つの異なる接続を開くことはできません。量産コードはアプリケーション名を指定しました。したがって、うまくいきました。テストコードはしませんでした。 Application Name=引数を指定すると、バグが修正されました。

4
briantyler

ところで、このような明示的なトランザクションを使用する場合は、SaveChanges(false)をAcceptChanges()と組み合わせて使用​​することを検討してください。

そうすることで、SaveChanges(false)で何かが失敗した場合、ObjectContextは変更を破棄していないため、後で再適用したり、エラーロギングなどを行うことができます。

詳細については、この投稿を参照してください: http://blogs.msdn.com/alexj/archive/2009/01/11/savechanges-false.aspx

乾杯

アレックス

3
Alex James

問題は、2つの異なるDataContextが2つの異なる接続を効果的に作成することです。

その場合、トランザクションは分散トランザクションに昇格する必要があります。あなたの問題は、サーバーまたはクライアントでのMS DTC(Microsoft分散トランザクションコーディネーター)の構成に起因すると思います。たとえば、MSDTCのリモート接続を許可するようにサーバーが構成されていない場合、そのような例外が発生します。

たとえば、MSDTCの問題のトラブルシューティングについては このMSページ を参照できます。Googleには記事/フォーラムの質問が満載です。

さて、それは何か他のものかもしれませんが、それは本当にそれがMSDTC問題であるように聞こえます。

1
Denis Troller

MSDTCトランザクションの失敗を診断する方法に関する別の質問に回答を書きました。

あなたはその答えが役に立ちます。

SQL ServerでMSDTCを有効にするにはどうすればよいですか?

0
Davy Landman

MQキューからメッセージを読み取って処理し、SQL 2005 Express Editionデータベースに格納するときにDTCを使用すると、同様のエラーが発生しました。 2005年かそれともExpress Express版がこの問題を引き起こしたのかを最後まで調査する時間はありませんが、2008 Standardに切り替えると、その特定の動作が消えてしまいました。

0