TransactionScope TransactionAborted异常-事务未回滚.应该是这样吗?
本文关键字:是这样吗 TransactionAborted 异常 事务 TransactionScope | 更新日期: 2023-09-27 18:04:55
(SQL SERVER 2008)如果在TransactionScope (.Complete())中发生事务超时错误,您会期望事务回滚吗?
更新:错误实际上是在右花括号中抛出的(即。dispose()),而不是。complete()。完整错误是:
The transaction has aborted. System.Transactions.TransactionAbortedException TransactionAbortedException System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.TimeoutException: Transaction Timeout
--- End of inner exception stack trace ---
at System.Transactions.TransactionStateAborted.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.InternalDispose()
at System.Transactions.TransactionScope.Dispose()
据我所知,事务没有回滚,表保持锁定,直到我对SPID/session_id发出KILL。
我使用DBCC OPENTRAN来获取最旧的事务,然后KILL它。我已经尝试了KILL WITH STATUS,但是得到一个消息,没有状态可用,因为没有任何东西正在回滚。sys. SPID/session_id的状态。Dm_exec_sessions正在"睡眠"。代码片段:
try
{
using (var transaction = new TransactionScope())
{
LOTS OF WORK CARRIED OUT WITH LINQ ENTITIES/SubmitChanges() etc.
transaction.Complete(); //Transaction timeout
}
return result;
}
catch (Exception ex)
{
logger.ErrorException(ex.Message, ex);
result.Fail(ex.Message);
return result;
}
更新:问题还没有完全解决,但如果其他人有这个问题,请提供进一步的信息。
- 我使用LINQ到SQL,在事务范围内,我调用context.SubmitChanges()。我做了很多手术。
- 在开发中,如果我在调用SubmitChanges()之前睡眠线程60秒(默认TransactionScope超时为60秒),那么在调用TransactionScope. complete()(该操作对事务的状态无效)时,我会得到不同的错误。
- 如果我睡了60秒后。submitchages()和之前。complete()然后我得到"交易已终止-系统。"TimeoutException: Transaction Timeout' 但是注意,在我的开发机器上,当使用DBCC opentran时,没有发现打开的事务-这是你所期望的,因为你希望事务回滚。
- 如果我然后在这个问题的底部添加代码(对不起,无法让网站在这里插入它)到我的配置文件中,将TransactionScope超时增加到2分钟,事情再次开始工作(研究表明,如果这不起作用,可能会在机器中设置。配置低于优先级的配置)。
- 虽然这将停止事务中止,但由于更新的性质,这确实意味着核心业务表上的锁可能长达2分钟,因此使用默认SqlCommand超时30秒的其他select命令将超时。虽然不理想,但总比一个开放的事务坐在那里,完全阻碍应用程序要好。
- 几天前,我们有一个灾难性的发布,这意味着我们在升级过程中耗尽了磁盘空间(!),所以我们最终使用了收缩数据库功能,这显然会导致性能问题。
我觉得数据库的重建和一些业务功能的重新思考…
我认为TransactionAbortedException实际上是一个超时。如果是这样,你会发现TransactionAbortedException的InnerException是一个超时。
您应该能够通过确保transactionscope的超时时间比命令超时时间长来消除它。
尝试将事务范围更改为如下内容:
new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(60))
并在上下文中设置显式超时。应该是这样的:
myContext.CommandTimeout = 30; //This is seconds
我通过修改"物理文件" machine.config来解决这个问题。
1。你必须本地化文件:
- 32位: C:'Windows'Microsoft.NET'Framework'v4.0.30319'Config' machine . Config
- 64位: C:'Windows'Microsoft.NET'Framework64'v4.0.30319'Config'machine.config
2。您必须添加以下代码:
<system.transactions>
<defaultSettings timeout="00:59:00" />
</system.transactions>