2

NET Framework 4.5 を使用して発生する分散トランザクションの問題に取り組んでいます。Framework 4.0 を使用してマシン (および開発サーバー) でアプリを実行しようとすると、コンポーネントは正常に動作します。fwk4.5 を自分のマシンにインストールして実行したときに問題が発生しました。フレームワークをインストールしただけで、ソース コードを変更したり、アセンブリのターゲット フレームワークを変更したりしませんでした。

Entity Framework と分散トランザクションの動作が fwk4.0 以降に変更された場合、なぜそれが起こっているのかを知る必要があります。

私はたくさん読んだのですが、まだ理解できませんでした。どんな助けも非常に高く評価されます。

敬具、ディエゴ

エラーを再現できる簡単なコード サンプルを次に示します。

注: トランザクションの前に ObjectContext 接続が手動で開かれていない場合、正常に動作することに注意してください。



public static bool DoTran_ObjectContext()
        {
            String strc = ConfigurationManager.ConnectionStrings["TestDB2Entities"].ConnectionString; //"metadata=res://*/TestDb2Model.csdl|res://*/TestDb2Model.ssdl|res://*/TestDb2Model.msl;provider=System.Data.SqlClient;provider connection string="data source=.\sqlexpress;initial catalog=TestDB2;integrated security=True;pooling=False;multipleactiveresultsets=True;application name=EntityFramework""
            ObjectContext oc = new ObjectContext(strc);

            //this line causes enlist error at the end of function/////
            oc.Connection.Open();
            ///////////////////////////////////////////////

            var t = (from s in oc.CreateObjectSet() where s.Id == 2 select s).FirstOrDefault();

            t.Valor = "Cambiado_" + DateTime.Now;

            using (TransactionScope scope2 = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
            {

                String cstr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; //"Data Source=.\\sqlexpress;Initial Catalog=TestDB2;Integrated Security=True";
                System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(cstr);
                conn.Open();
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = "insert into Tabla1_Db2 values('" + DateTime.Now.ToString() + "')";

                SqlTransaction tran = conn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
                cmd.Transaction = tran;
                cmd.ExecuteNonQuery();

                tran.Commit();
                conn.Close();

                oc.SaveChanges();

                scope2.Complete();
            }

            //On this line the error is thrown
            var t2 = (from s in oc.CreateObjectSet() where s.Id == 2 select s).FirstOrDefault();

            return true;
        }

エラー:

「分散トランザクションが完了しました。このセッションを新しいトランザクションまたは NULL トランザクションに登録してください。」

ありがとう!

4

1 に答える 1

1

この問題は、ここに記載されているスコープの 1 つで IsolationLevel が異なることに関連していると思います

ネストされた TransactionScope オブジェクトを使用する場合、ネストされたすべてのスコープがアンビエント トランザクションに参加する場合は、まったく同じ分離レベルを使用するように構成する必要があります。ネストされた TransactionScope オブジェクトがアンビエント トランザクションに参加しようとしても、別の分離レベルが指定されている場合、ArgumentException がスローされます。

デフォルトの分離レベルは Serializable です。呼び出し元が関与している Serializable トランザクションを実行する場合、トランザクションを ReadCommitted に設定します。

于 2013-05-27T20:25:30.640 に答える