TransactionScope在处置之前中止了交易

Pau*_*jto 7 c# sql transactions

当使用TransactionScope时,它表示如果内部执行的代码回滚事务,那么父事务也将回滚.这对我有好处.但是当处置该范围时,它会抛出异常,这意味着事务已经回滚并且已中止.那么处理这个并正确处理范围的正确方法是什么?

    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
                    using (var conn = GetConnection())
                    {
                            string query = 
              @"some query that may contain transaction itself 
              or some SP whith transaction included"

                            using (var command = new SqlCommand(query, conn))
                                command.ExecuteNonQuery();
                        }
                    }
                    scope.Complete();
    } // Exception here
Run Code Online (Sandbox Code Playgroud)

小智 7

scope.Dispose()TransactionAborted即使scope.Complete()被调用也可能抛出异常.例如,一些存储过程足够聪明,可以使用T-SQL TRY/CATCH构造w/o向调用者抛出异常来处理异常并在T-SQL脚本中中止事务.所以我认为我建议的最安全的方法如下:

try
{
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        try
        {
            using (var conn = GetConnection())
            {
                string query = 
                @"some query that may contain transaction itself 
                or some SP whith transaction included"

                using (var command = new SqlCommand(query, conn))
                command.ExecuteNonQuery();
            }
        }
        catch (SqlException ex)
        {
            // log SQL Exception, if any
            throw;  // re-throw exception
        }

        scope.Complete();
    }
}
catch (TransactionAbortedException ex)
{
    // we can get here even if scope.Complete() was called.
    // log TransactionAborted exception if necessary
}
Run Code Online (Sandbox Code Playgroud)

并且不要担心处置TransactionScope.scope.Dispose在抛出TransactionAborted异常之前执行任何必要的清理工作.