5

診断上の理由からデータベースの状態の整合性チェックを実行しようとしていたため、変更 ORM クエリを TransactionScope でラップし、診断を実行する 2 番目のクエリと組み合わせて次のようにしました。

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

これは手作業で作成された ORM であり、これらの呼び出しは両方とも、最下部にあるネストされたトランザクション スコープでそれぞれの役割を果たします。つまり、掘り下げると、DeleteItem() には using (TransactionScope newScope = new TransactionScope(TransactionScopeOptions.Required, _maxTimeout) {...}

と CheckIntegrity() も同じです。

ほとんどの場合、問題なく動作していますが、奇妙な状況に遭遇しました。誰かがクエリに不適切な入力を行うと、DeleteItem() 呼び出しで例外がスローされる可能性があります。その例外は完全にキャッチされ、ラッパーの下のスタック レベルで処理されます。TransactionScope をネストするに、例外もスローされると思います。

しかし、CheckIntegrity() 呼び出しでネストされたスコープの作成に到達すると、CreateAbortingClone コンストラクターから「Transaction was aborted error」がスローされます。内部例外は null です。

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 に答える