【问题标题】:TransactionScope TransactionAborted Exception - transaction not rolled back. Should it be?TransactionScope TransactionAborted 异常 - 事务未回滚。应该是吗?
【发布时间】:2011-08-10 06:39:43
【问题描述】:

(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.dm_exec_sessions 中 SPID/session_id 的状态为“睡眠”。代码sn-p:

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;
}

更新:
问题尚未完全解决,但如果其他人有此问题,请提供更多信息。

  1. 我正在使用 LINQ to SQL,并在事务范围内调用 context.SubmitChanges()。我正在执行很多插入操作。 SQL Server 探查器指示为每个插入发出单独的 INSERT 语句。
  2. 在开发中,如果我在调用 SubmitChanges() 之前让线程休眠 60 秒(默认 TransactionScope 超时为 60 秒),那么在调用 TransactionScope.Complete() 时会出现不同的错误(该操作对于交易。)。
  3. 如果我在 .SubmitChages() 之后和 .Complete() 之前睡了 60 秒,那么我会得到 '事务已中止 - System.TimeoutException: Transaction Timeout'
  4. 但请注意,在我的开发机器上,使用 DBCC opentran 时未找到打开的事务 - 这是您所期望的,因为您期望事务回滚。
  5. 如果我随后将这个问题底部的代码(抱歉无法让网站在此处插入)添加到我的配置文件中,这会将 TransactionScope 超时时间增加到 2 分钟,事情又开始工作了(研究表明,如果这不起作用,可能 machine.config 中的设置低于优先级)。
  6. 虽然这将停止事务中止,但由于更新的性质,这确实意味着核心业务表上的锁定可能长达 2 分钟,因此使用默认 SqlCommand 超时 30 秒的其他选择命令将超时。不理想,但比坐在那里完全阻止应用程序的公开交易要好。
  7. 几天前,我们发布了一个灾难性的版本,这意味着我们在升级过程中耗尽了磁盘空间 (!),因此我们最终使用了收缩数据库功能,这显然会在您使用后导致性能问题。
  8. 我觉得数据库正在重建,并且正在重新考虑一些即将推出的业务功能......

【问题讨论】:

  • .Complete()期间超时是否应该回滚?
  • 你可能想检查这个问题stackoverflow.com/questions/6159876/…。特别是“交易绑定”可能与您的问题有关。
  • 干杯。问题已更新,因为看起来异常实际上发生在右大括号 .Dispose()....

标签: c# sql-server transactionscope


【解决方案1】:

我认为 TransactionAbortedException 实际上是超时。如果是这样你应该会发现 TransactionAbortedException 的 InnerException 是超时。

您应该能够通过确保事务范围的超时时间长于命令超时来摆脱它。

尝试将事务范围更改为以下内容:

new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(60))

并在您的上下文中设置显式超时。应该是这样的:

myContext.CommandTimeout = 30; //This is seconds

【讨论】:

  • 谢谢。一定会检查出来的。正如您所说,这是一个超时,但我不明白为什么事务没有回滚并且表保持锁定状态。我假设更改尚未提交,但我确实需要尝试在本地复制问题。我想我可以通过使用上面的代码来做到这一点
  • @MT 如果这是原因,您应该能够进行一些长时间运行的查询,只需将 transactionscope 超时设置为非常短的时间,问题应该会出现......希望:)
  • 虽然我的问题是在调用 transactionScope.Complete() 之前返回,但这个答案导致了另一个为异步超时提供解决方案的答案。谢谢! stackoverflow.com/questions/24593070/…
【解决方案2】:

我通过修改“物理文件ma​​chine.config解决了这个问题。

1.您必须本地化文件:

  • 32 位: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machie.config
  • 64 位: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config

2.您必须添加以下代码:

<system.transactions>
     <defaultSettings timeout="00:59:00" />
</system.transactions>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 2013-10-16
    • 2015-12-05
    • 2012-12-28
    • 2022-07-22
    • 2016-08-14
    • 1970-01-01
    相关资源
    最近更新 更多