TransactionScope TransactionAborted异常-事务未回滚.应该是吗? [英] TransactionScope TransactionAborted Exception - transaction not rolled back. Should it be?

查看:214
本文介绍了TransactionScope TransactionAborted异常-事务未回滚.应该是吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(SQL SERVER 2008)如果在TransactionScope(.Complete())内发生事务超时错误,您是否希望事务回滚?

(SQL SERVER 2008) If a Transaction Timeout error occurs within a TransactionScope (.Complete()) would you expect the transaction to be rolled back?

更新:
该错误实际上是在右花括号(即.Dispose())而不是.Complete()中引发的.完整错误是:

Update:
The error is actually being thrown in the closing curly brace (i.e. .Dispose()), not .Complete(). Full error is:

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之前,事务不会回滚并且表保持锁定状态.

As far as I can tell the transaction is not rolled back and the tables remained locked until I issued a KILL against the SPID/session_id.

我使用DBCC OPENTRAN来获取最早的事务,然后将其杀死.我已尝试使用状态杀死(KILL WITH STATUS),但收到一条消息,因为没有任何回滚,因此没有可用的状态.sys.dm_exec_sessions中SPID/session_id的状态为正在休眠".代码段:

I used DBCC OPENTRAN to get the oldest transaction and then KILL it. I have tried KILL WITH STATUS but get a message that no status is available as nothing is being rolled back. Status of the SPID/session_id in sys.dm_exec_sessions is 'sleeping'. Code snippet:

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

更新:
问题尚未完全解决,但其他任何人都应该解决此问题时,请提供更多信息.

UPDATE:
Problem is not entirely solved, but further information should anyone else have this problem.

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

  1. I am using LINQ to SQL and within the transaction scope I call context.SubmitChanges(). I am carrying out a lot of inserts. SQL Server profiler indicates that a separate INSERT statement is issued for each insert.
  2. In development, if I sleep the thread for 60 seconds (default TransactionScope timeout is 60 seconds) BEFORE calling SubmitChanges() then I get a different error when calling TransactionScope.Complete() (The operation is not valid for the state of the transaction.).
  3. If I sleep for 60 seconds AFTER .SubmitChages() and just before .Complete() then I get 'The transaction has aborted - System.TimeoutException: Transaction Timeout'
  4. NOTE however that on my dev machine no open transactions are found when using DBCC opentran - which is what you would expect as you would expect the transaction to rollback.
  5. If I then add the code at the bottom of this question (sorry couldn't get the website to insert it here) to my config file which increases the TransactionScope timeout to 2 minutes, things start working again (research indicates that if this doesn't work there could be a setting in machine.config that is lower than this that is taking precedence).
  6. Whilst this will stop the transaction aborting, due to the nature of the updates, it does mean that locks on a core business table could be up to 2 minutes so other select commands using the default SqlCommand timeout of 30 seconds will timeout. Not ideal, but better than an open transaction sitting there and totally holding up the application.
  7. A few days ago we had a disastrous release that meant we ran out of diskspace mid upgrade (!) so we did end up using the shrink database functionality which apparently can cause performance problems after you have used it.
  8. I feel a rebuild of the database and a rethink of some business functionality coming on...

推荐答案

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

I'm thinking that the TransactionAbortedException is actually a timeout. If so you should find that the InnerException of the TransactionAbortedException is a timeout.

通过确保transactionscope的超时时间长于命令超时时间,您应该能够摆脱它.

You should be able to get rid of it by making sure that the timeout of the transactionscope is longer than the command timeout.

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

Try changing the transaction scope to something like this:

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

,并在上下文中设置一个显式超时.应该是这样的:

And also set an explicit timeout on your context. Should be something like:

myContext.CommandTimeout = 30; //This is seconds

这篇关于TransactionScope TransactionAborted异常-事务未回滚.应该是吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆