TransactionScope会在某些机器上自动升级到MSDTC吗?

时间:2009-11-06 22:24:34

标签: c# .net transactions transactionscope msdtc

7 个答案:

答案 0 :(得分:71)

如果连接未同时打开,SQL Server 2008可以在一个SQLConnection中使用多个TransactionScope而不会升级,这会导致多个“物理”TCP连接,因此需要升级

我看到你的一些开发人员拥有SQL Server 2005而其他人拥有SQL Server 2008.你确定你已经正确识别出哪些正在升级而哪些不升级?

最明显的解释是,SQL Server 2008的开发人员不会升级。

答案 1 :(得分:58)

我对该主题的研究结果:

enter image description here

请参阅Avoid unwanted Escalation to Distributed Transactions

我仍在调查Oracle的升级行为: Do transactions spanning multiple connections to same DB escalate to DTC?

答案 2 :(得分:31)

该代码 会在连接到2005时导致升级。

查看MSDN上的文档 - http://msdn.microsoft.com/en-us/library/ms172070.aspx

  

SQL Server 2008中的可升级事务

     

在.NET Framework 2.0版中   和SQL Server 2005,开了第二个   TransactionScope内部的连接   会自动推广   交易到完全分发   交易,即使两个连接   使用相同的连接   字符串。在这种情况下,分布式   事务增加了不必要的开   这会降低性能。

     

从SQL Server 2008开始   .NET Framework 3.5版,   本地交易不再   晋升为分布式交易   如果在中打开另一个连接   之前的交易   交易已结束。这需要   如果你没有改变你的代码   已经使用连接池和   参与交易。

我无法解释为什么Dev 3:Windows 7 x64,SQL2005成功和Dev 4:Windows 7 x64失败。你确定不是反过来吗?

答案 3 :(得分:9)

我不知道为什么这个答案被删除了,但这似乎有一些相关的信息。

于2010年8月4日17:42 Eduardo

回答
  1. 在连接字符串上设置 Enlist = false ,以避免在事务中自动登记。

  2. 事务范围中的
  3. Manually enlist connection as participants。 [original article已过时] 或者这样做:How to prevent automatic MSDTC promotion [archive.is]

答案 4 :(得分:2)

我不太确定嵌套连接是否是问题。我正在调用SQL服务器的本地实例并且它没有生成DTC ??

    public void DoWork2()
    {
        using (TransactionScope ts2 = new TransactionScope())
        {
            using (SqlConnection conn1 = new SqlConnection("Data Source=Iftikhar-PC;Initial Catalog=LogDB;Integrated Security=SSPI;"))
            {
                SqlCommand cmd = new SqlCommand("Insert into Log values(newid(),'" + "Dowork2()" + "','Info',getDate())");
                cmd.Connection = conn1;
                cmd.Connection.Open();
                cmd.ExecuteNonQuery();

                using (SqlConnection conn2 = new SqlConnection("Data Source=Iftikhar-PC;Initial Catalog=LogDB;Integrated Security=SSPI;Connection Timeout=100"))
                {
                    cmd = new SqlCommand("Insert into Log values(newid(),'" + "Dowork2()" + "','Info',getDate())");
                    cmd.Connection = conn2;
                    cmd.Connection.Open();
                    cmd.ExecuteNonQuery();
                }
            }

            ts2.Complete();
        }
    }

答案 5 :(得分:1)

如果您使用内部多个连接访问,则TransactionScope始终会升级为DTC事务。上面的代码禁用DTC的唯一方法是,如果很有可能两次都从连接池获得相同的连接。

“麻烦的是,在我们开发人员的一半机器上,我们可以在禁用MSDTC的情况下运行。” 你确定它已被禁用;)

答案 6 :(得分:0)

确保您的connectionString没有将池设置为false。这将为TransactionScope中的每个新SqlConnection产生一个新连接,并将其升级为DTC。