TransactionScope TransactionAborted Exception - 事务未回滚。应该是吗?

时间:2011-08-10 06:39:44

标签: c# sql-server transactionscope

(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 WITH STATUS但是收到一条消息,说明没有任何状态可用,因为没有回滚。 sys.dm_exec_sessions中SPID / session_id的状态为“正在休眠”。代码段:

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. 在开发中,如果我将线程休眠60秒(默认的TransactionScope超时为60秒),在调用SubmitChanges()之前,我在调用TransactionScope.Complete()时会遇到不同的错误(该操作对于交易。)。
  3. 如果我睡了60秒后.SubmitChages()和之前.Complete()然后我得到 '事务已中止 - System.TimeoutException:Transaction Timeout'
  4. 但是请注意,在我的开发机器上,使用DBCC opentran时没有找到打开的事务 - 这是您期望事务回滚的结果。
  5. 如果我然后在这个问题的底部添加代码(抱歉无法让网站将其插入此处)到我的配置文件,这会将TransactionScope超时增加到2分钟,事情再次开始工作(研究表明,如果这不起作用可能在machine.config中设置低于优先级的设置。
  6. 虽然这会阻止事务中止,但由于更新的性质,它确实意味着核心业务表上的锁可能长达2分钟,因此使用默认SqlCommand超时30秒的其他选择命令将超时。不理想,但比坐在那里并完全支持申请的公开交易更好。
  7. 几天前,我们发布了一个灾难性的版本,这意味着我们在升级过程中耗尽了磁盘空间(!),因此我们最终使用了收缩数据库功能,这显然会在您使用它后导致性能问题。
  8. 我感觉重建了数据库并重新考虑了一些商业功能......

        

2 个答案:

答案 0 :(得分:14)

我认为TransactionAbortedException实际上是一个超时。如果是这样,您应该发现TransactionAbortedException的InnerException是超时。

你应该能够通过确保transactioncope的超时时间长于命令超时来摆脱它。

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

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

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

myContext.CommandTimeout = 30; //This is seconds

答案 1 :(得分:0)

我解决了修改“物理文件 machine.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. 您必须添加以下代码:

 var identity = new ClaimsIdentity(new[]
 {
  new Claim(ClaimTypes.Name,"Admin"),
  new Claim(ClaimTypes.Role,"Administrator")
  , "ApplicationCookie");

   var ctx = Request.GetOwinContext();
   var authManager = ctx.Authentication;
   authManager.SignIn(identity);
   return RedirectToAction("Index", "Home", null);
  }