【发布时间】:2016-10-21 05:45:23
【问题描述】:
我正在以下列方式使用TransactionScope
using (var scope = new TransactionScope())
{
using (var conn = SQLHelpers.GetSQLConnection())
{
//commands here
}
scope.Complete();
}
有时我在调用scope.Complete() 时收到TransactionAbortedException,因为事务已经回滚,我使用分析器确定问题是死锁。
异常事务(进程 ID 59)在锁定资源上与另一个进程死锁,并已被选为死锁牺牲品。重新运行事务。
我已经找到了死锁的原因,但是它让我想知道为什么这个错误没有冒泡到TransactionAbortedException,所以我确实可以为那个特定的情况重新运行事务。 内部异常不包含任何可以指示实际错误的信息。
检测TransactionAbortedException 作为重新运行事务的原因是否安全?
到目前为止,我已经看到了以下内部异常:
1) 死锁
2) 超时
3) '连接已关闭'
4) .. 其他?
仅在其中一种情况下,重新运行事务似乎是合适的,但是如果保证回滚,您可以将其推广到所有情况。这个问题可以重新表述为“TransactionAbortedException 是否保证事务已回滚”?
【问题讨论】:
-
你看到 TransactionAbortedException 的 InnerException 是超时了吗?
-
不,唯一的
InnerException是:The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.,我得到这个是因为当事务被死锁回滚时,我调用了scope.Complete -
试试这个 if (Transaction.Current.TransactionInformation.Status == TransactionStatus.Committed) { scope.Complete(); }
-
@VladimirBaranov 没有特别询问死锁问题 - 我询问是否有任何 (db) 副作用需要重新运行(例如重新插入两次)当你遇到
TransactionAbortedException时你刚刚运行的任何东西- 会稍微更新 q -
我认为创建一个Transaction对象并将其添加到TransactionScope中应该是一个好主意。 (交易范围(交易))。您可以在每个 sql 命令之后检查它,以了解何时或为什么会出现死锁。 (Transaction.TransactionInformation.Status)
标签: c# sql-server