C# 在嵌套事务作用域中打开两个SQL连接时挂起事务

C# 在嵌套事务作用域中打开两个SQL连接时挂起事务,c#,sql-server,C#,Sql Server,我试图理解下面代码中的错误: using (var scope1 = new TransactionScope()) { var connection1 = new SqlConnection("..."); connection1.Open(); using (var scope2 = new TransactionScope()) { SqlConnection connection2 = new SqlConnection("...");

我试图理解下面代码中的错误:

using (var scope1 = new TransactionScope())
{
    var connection1 = new SqlConnection("...");
    connection1.Open();

    using (var scope2 = new TransactionScope())
    {

        SqlConnection connection2 = new SqlConnection("...");
        connection2.Open();

        connection2.Close();
        scope2.Complete();

    }

    connection1.Close();
    scope1.Complete();
}
应用程序非常复杂,因此存在TransactionScope的嵌套块。在上面的代码中,当连接打开时,事务将在SQL Server中创建,因此实际上会创建两个事务,因为连接打开了两次

我通过调用以下SQL语句对此进行了检查:

SELECT * FROM sys.sysprocesses WHERE open_tran = 1
scope1中的环境事务完成后,数据库中仍有一个事务。connection2.Close创建的事务仍挂起。我的问题是为什么这个事务仍然存在,以及如何更正代码

编辑:


我想使用TransactionScope之外定义的一个SQL连接可能是一个答案,但可能存在更好的方法?

该代码将需要一个分布式事务,因为您同时打开了两个单独的SqlConnection对象。如果在启动第二个TransactionScope之前关闭SqlConnection,则初始连接和事务将被重新使用,并且不需要DTC传输操作

无论如何,我认为这是DTC事务的一个无害的副作用,它的跟踪方式有点不同。检查

  select st.session_id, is_local, is_enlisted, at.transaction_state
  from sys.dm_tran_session_transactions st
  join sys.dm_tran_active_transactions at
    on at.transaction_id = st.transaction_id 
对于我来说,它为打开的第二个会话spid 65输出一行,并指示事务已提交

session_id  is_local is_enlisted transaction_state
----------- -------- ----------- -----------------
65          0        1           6

事务状态=6表示事务已提交

打开连接2时是否出现异常?尝试向Connection2代码添加一个catch,看看是否出现异常。使用语句有时会掩盖异常。我想在连接2关闭之前您会遇到一个异常。