C# TransactionScope和手动回滚事务之间的区别?

C# TransactionScope和手动回滚事务之间的区别?,c#,sql-server,sql-server-2008,C#,Sql Server,Sql Server 2008,我正在做一个别人以前开发的项目。在程序中,它执行以下操作: reportConnection = new SqlConnection(sConnStr); reportConnection.Open(); try { using (SqlTransaction trans = reportConnection.BeginTransaction(IsolationLevel.ReadUncommitted)) {

我正在做一个别人以前开发的项目。在程序中,它执行以下操作:

 reportConnection = new SqlConnection(sConnStr);
 reportConnection.Open();
 try
 {
     using (SqlTransaction trans = reportConnection.BeginTransaction(IsolationLevel.ReadUncommitted))                    

     {
        ......
        using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans))
        {
            ....
        }
        trans.Commit();
     }
}
catch (Exception ex)
{
    Logger ....
}
fianlly
{
    if (reportConnection != null)
    {
        ((IDisposable)reportConnection).Dispose();
    }

}
我看到的问题是,如果using块中存在错误,它不会回滚事务。因此,这里是第一个问题:如果出现错误,将不会提交传输(也不会回滚),但会处理连接(不会处理传输)。在这种情况下,它会产生什么副作用?它是否会创建一个打开的孤立连接/事务?这样,会不会造成死锁

我做了一些搜索,似乎首选的方法是使用transactionscope(下面的代码来自microsoft):

我的第二个问题是:如果我像下面这样手动操作会怎么样。使用transactionscope有什么好处?它们真的是一样的吗

reportConnection = new SqlConnection(sConnStr);
reportConnection.Open();
try
 {
     using (SqlTransaction trans = reportConnection.BeginTransaction(IsolationLevel.ReadUncommitted))                    

     {
        try
        {
            ......
            using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans))
            {
                ....
            }
            trans.Commit();
        }
        catch
        {
            try
            {
                // incase rollback has error
                trans.Rollback();
            }
            catch
            {
            }
        }
     }
}
catch (Exception ex)
{
    Logger ....
}
fianlly
{
    if (reportConnection != null)
    {
        ((IDisposable)reportConnection).Dispose();
    }

}

谢谢。

这将在
SqlTransaction
文档中介绍:

Dispose应该回滚事务。但是, Dispose是特定于提供程序的,不应替换调用回滚

摘自:

我想这一切都取决于你有多偏执,当你认为坏的实现可能无法正常工作时,你会试图强迫它们正常工作。第一个代码示例绝对是最简单的,只有当您的提供者不能正常工作时,它才会失败

编辑复杂性示例-您的最后一个代码段应为:

try { /*...*/ 
    using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans)) {
        /*...*/ }
    trans.Commit();
} catch { try { trans.Rollback(); } catch {} throw; }

?

try { /*...*/ 
    using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans)) {
        /*...*/ }
    trans.Commit();
} catch { try { trans.Rollback(); } catch {} throw; }
try { /*...*/ 
    using (SqlCommand cmd = new SqlCommand(sSQL, reportConnection, trans)) {
        /*...*/ }
} catch { try { trans.Rollback(); } catch {} throw; }
trans.Commit();