使用相同连接的TransactionScope和方法调用

时间:2016-11-21 11:33:24

标签: c# sql-server-2012 transactions ado.net transactionscope

我正在使用TransactionScope创建一个包含多个sql语句事务的方法。现在我需要调用另一个也使用相同连接的方法,并在connection.Open()收到以下异常:

  

分布式事务管理器(MSDTC)的网络访问已经完成   禁用。请在安全性中启用DTC以进行网络访问   使用组件服务管理的MSDTC配置   工具。

所以这是伪代码:

public static void Method1()
{
    using (TransactionScope scope = new TransactionScope())
    {
        bool success = true; // will be set to false in an omitted catch
        using (var connection = new SqlConnection(ConnectionString1))
        {
           // ...
           if(somethingHappened)
               Method2();
        }
        if(success)
            scope.Complete();
    }
}

public static void Method2()
{
    using (var connection = new SqlConnection(ConnectionString1))
    {
        connection.Open(); // BOOOM!
        // ...
    }
}

如何避免此异常而不重复Method2中的Method1代码?

3 个答案:

答案 0 :(得分:2)

如果在同一TransactionScope下打开了多个连接,它将自动升级到DTC。

您需要在致电Method2之前关闭第一个连接。

public static void Method1()
{
    using (TransactionScope scope = new TransactionScope())
    {
        bool success = true; // will be set to false in an omitted catch

        bool isSomethingHappened
        using (var connection = new SqlConnection(ConnectionString1))
        {
           isSomethingHappened = // Execute query 1
        }

       if(somethingHappened)
           Method2();

        if(success)
            scope.Complete();
    }
}

答案 1 :(得分:2)

同一事务范围下的嵌套连接将提升为分布式事务。

从SQL Server 2008及以上版本,同一事务范围内的多个(非嵌套)连接不会升级到分布式事务。

请参阅this问题以获取更多信息

答案 2 :(得分:0)

我不知道确切的答案,但我会将连接作为成员,并跟踪它是否已打开。

然后在Method1和Method2中,我将通过一些GetConnection()获得连接,这将在首次使用时打开连接。

阅读完评论后,我会建议一个私有的DoMethod2,它接受一个连接对象。