当使用 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
最佳答案
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
}
并且不用担心处置 TransactionScope
。 scope.Dispose 在抛出 TransactionAborted
异常之前执行任何必要的清理工作。
关于c# - TransactionScope 在处置前已中止交易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21312126/