TransactionScope正在包装ORM调用,TransactionStateAbortedCreateAbort

本文关键字:调用 TransactionStateAbortedCreateAbort ORM 包装 TransactionScope | 更新日期: 2023-09-27 18:21:52

由于诊断原因,我们试图对数据库状态进行一些完整性检查,因此我们将修改后的ORM查询封装在TransactionScope中,并与运行诊断的第二个查询结合在一起-类似于以下内容:

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, _maxTimeout))
{
    ORM.DeleteItem();
    ORM.CheckIntegrity();
    scope.Complete();
}

这是一个手工滚动的ORM,这两个调用最终都在底部的嵌套事务范围中发挥作用。换句话说,当您向下挖掘时,DeleteItem()具有使用(TransactionScope newScope=新TransactionScope(TransactionScopeOptions.Required,_maxTimeout){…}

并且CheckIntegrity()也具有相同的功能。

在大多数情况下,它运行良好,但我遇到了一个奇怪的情况。当有人向查询输入了一些错误的输入时,DeleteItem()调用可能会引发异常。该异常在包装器下面的堆栈级别被完全捕获和处理。我相信在嵌套TransactionScope之前也会抛出异常。

但是,当我们进入CheckIntegrity()调用中的嵌套作用域创建时,它会从CreateAbortingClone构造函数抛出一个"Transaction was aborted error"。内部异常为null。

大多数其他提到的CreateAbortingClone交互都与DTC升级(或失败)有关,内部异常反映了这一点。

我推断CheckIntegrity()调用上的中止异常是由于DeleteItem()抛出了一个异常——尽管它被吞噬了。

A) 这是一个正确的推论吗?TransactionScope是否对引发、处理或不处理的任何异常敏感?

B) 在调用CheckIntegrity()之前,有什么方法可以检测到这一点吗?我的意思是,除了重新执行ORM以让异常渗透或添加其他全局标志之外?

谢谢标记

TransactionScope正在包装ORM调用,TransactionStateAbortedCreateAbort

我只知道这是如何与EF(实体框架)一起工作的

 using (var context = new MyContext(this._connectionString))
 {
    using (var dbContextTransaction = context.Database.BeginTransaction())
    {

    }
}

然后将事务链接到上下文。我不知道你的代码是如何建立这种联系的,但可能是一些花哨的内置内容。

然后最好将其包装在尝试/捕获中

try
{
   // do-stuff
   context.SaveChanges();
   //NB!!!!!!
   //----------------------
   dbContextTransaction.Commit();
}
catch (Exception ex)
{
    dbContextTransaction.Rollback();
    //log why it was rolled back
    Logger.Error("Error during transaction,transaction rollback", ex);
}

所以最后的代码看起来像

 using (var context = new MyContext(this._connectionString))
 {
    using (var dbContextTransaction = context.Database.BeginTransaction())
    {
         try
         {
              // do-stuff //
              context.SaveChanges();
              ///////////////////////
              //if any exception happen, changes wont be saved unless Commit is called 
              //NB!!!!!!
              //----------------------
              dbContextTransaction.Commit();
         }
         catch (Exception ex)
         {
              dbContextTransaction.Rollback();
              //log why it was rolled back
              Logger.Error("Error during transaction,transaction rollback", ex);
         }
    }
}