.Net Framework 4.5。分布式事务完成。在新事务或NULL事务中登记此会话

时间:2013-05-06 02:36:10

标签: .net-4.5 distributed-transactions objectcontext change-tracking

我正在处理使用.NET Framework 4.5发生的分布式事务问题。如果我尝试使用Framework 4.0在计算机(以及Dev Server)上执行应用程序,则组件可以正常工作。          当我在我的机器上安装fwk4.5并运行它时,问题就出现了。我只安装了框架,我从未更改源代码,也没有更改程序集上的目标框架。

如果在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;
        }

错误:

"Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction."

谢谢!

1 个答案:

答案 0 :(得分:1)

我认为问题与IsolationLevel在其中一个范围内有所不同here

  

使用嵌套的TransactionScope对象时,如果要加入环境事务,则必须将所有嵌套范围配置为使用完全相同的隔离级别。如果嵌套的TransactionScope对象尝试加入环境事务但它指定了不同的隔离级别,则抛出ArgumentException。

默认隔离级别是Serializable,如果调用者运行您参与其中的Serializable事务,则将您的Transaction设置为ReadCommitted。