【问题标题】:The transaction has aborted交易已中止
【发布时间】:2010-08-27 15:46:02
【问题描述】:

我有一个多线程 C# 应用程序,其中每个线程都有自己的一组数据库连接。每个线程都使用 TransactionScope / DTC。有时,我会收到“事务已中止”异常。这不是超时,因为它在开始事务后不到 2 秒内发生。

这是堆栈跟踪:

在 System.Transactions.TransactionStateAborted.BeginCommit(InternalTransaction tx,布尔 asyncCommit,AsyncCallback asyncCallback,对象 asyncState) 在 System.Transactions.CommittableTransaction.Commit() 在 System.Transactions.TransactionScope.InternalDispose() 在 System.Transactions.TransactionScope.Dispose() 在 MyNamespace.CallingMethod()

这种情况很少发生,比如在 100,000 笔交易中发生一次。

环境: 视窗服务器 2003 .Net 2.0 连接到 SqlServer 2005

关于为什么会发生这种情况的任何想法? 谢谢!

【问题讨论】:

  • SQL、DTC 或操作系统错误日志是否有任何其他详细信息?
  • 事件日志中带有该时间戳的任何条目?
  • 生产盒,因此很难在没有繁文缛节的情况下获得任何信息。我会看看我是否可以从事件日志中得到任何东西,这更容易。谢谢!
  • 操作系统事件日志中没有任何内容。到 sql 日志。
  • sql 日志中没有任何内容。看看性能指标是否有任何线索。

标签: c# .net sql-server sql-server-2005


【解决方案1】:

这个调用堆栈是来自你最里面的 InnerException 吗?如果您收到此异常,通常(但并非总是)有一个包含更多信息的 InnerException。

我的赌注是数据库死锁。

【讨论】:

  • 是的,这是最内在的例外。我可以访问死锁痕迹,但在此期间没有找到。
【解决方案2】:

你可以创建一个内存转储,指令可以在这里找到 http://blogs.msdn.com/b/joncole/archive/2007/03/29/creating-a-process-memory-dump.aspx

然后您可以使用 windbg 检查以揭示导致此问题的根异常。关于如何使用 windbg 检查托管异常有很多有用的信息。

同时,您可以使用 sql profiler 来监控在抛出异常时是否发生了任何 sql 错误。

【讨论】:

  • 我喜欢这个主意。我将再次尝试在 dev 中重新创建它并得到这个问题的答案。
  • 如果您有内存转储,我可以为您检查。你可以把它放在skydrive公共文件夹中。
【解决方案3】:

我认为这归因于网络不稳定。它非常罕见,而且已经好几个月没有抬起它那丑陋的脑袋了。

【讨论】:

    【解决方案4】:

    如果你们中的任何人遇到此问题,请注意我设法找到了解决方案和问题。在应用程序配置文件中,缺少连接字符串的属性,即“Enlist”。

    之前的连接字符串是 = <add name="HIS_Test_12" connectionString="server=OXYGEN\SQL2008ENT;database=CHIS_VN_12;UID=sa;Password=1234;Max Pool Size=100;Connect Timeout=200;" providerName="System.Data.SqlClient" />

    现在更新的连接字符串是=<add name="HIS_Test_12" connectionString="server=OXYGEN\SQL2008ENT;database=CHIS_VN_12;UID=sa;Password=1234;Max Pool Size=100;Connect Timeout=200;Enlist=False;" providerName="System.Data.SqlClient" />

    【讨论】:

      【解决方案5】:

      正如 Andreas 所说,看看 InnerExceptions。还连接 SQL Profiler 并查找任何死锁/终止。

      【讨论】:

        【解决方案6】:

        如果存在未提交的内部事务,也会发生此问题。如果您将事务范围放在 using 块中并且没有提交,则右括号将在 dispose 期间回滚所有事务。这可能导致事务已中止异常,没有内部异常。

        using (var outerScope = new TransactionScope())
        {
            using (var innerScope = new TransactionScope())
            {
                // Some operations to be done inside a transaction
                
                //innerScope.Complete()
            } // Dispose is called here and rolls back both inner and outer scope
            outerScope.Complete();
        }
        

        如果在事务中抛出 SqlException,它也会回滚事务,并且在处理异常时会变得非常混乱 (and possibly dangerous)。

        【讨论】:

          猜你喜欢
          • 2012-09-18
          • 2021-07-19
          • 2023-01-14
          • 2018-10-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多