5

出于诊断原因,我们试图对我们的数据库状态进行一些完整性检查,因此我们将修改 ORM 查询包装在 TransactionScope 中,并结合第二个运行诊断的查询 - 如下所示:

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

这是一个手动 ORM,这两个调用最终都在底部的嵌套事务范围内发挥作用。换句话说,当您深入挖掘时, DeleteItem() 使用 (TransactionScope newScope = new TransactionScope(TransactionScopeOptions.Required, _maxTimeout) {...}

和 CheckIntegrity() 也有相同的。

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

但是,当我们开始在 CheckIntegrity() 调用中创建嵌套范围时,它会从 CreateAbortingClone 构造函数中抛出“Transaction was aborted error”。内部异常为空。

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

我推断 CheckIntegrity() 调用中的中止异常是由于 DeleteItem() 引发了异常 - 即使它被吞下。

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

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

谢谢马克

4

1 回答 1

0

我只知道这如何与 EF(实体框架)一起使用

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

    using (var dbContextTransaction = context.Database.BeginTransaction())
    {


    }
}

然后将事务链接到上下文。我对您的代码如何建立这种联系并不熟悉,但可能是一些花哨的内置东西。

然后最好将其包装在 try/catch 中

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

    }
}
于 2015-09-27T16:04:36.530 回答