11

TransactionScope は、次のように Complete メソッドの呼び出しを想定しています。そうしないと、トランザクションはコミットされません。

using(TransactionScope scope = new TransactionScope())
{
    /* Perform transactional work here */

    scope.Complete();
}

成功を前提とした実装の方が適切ではないでしょうか? これは、標準的なケース (成功) で必要なコードが少なくなることを意味します。

例外または「Rollback」などのメソッドへの呼び出し (このメソッドは現在存在しません) の場合、トランザクションはロールバックされる可能性があります。

using(TransactionScope scope = new TransactionScope())
{
    /* Perform transactional work here */

     if(problemOccurred)
     {
         scope.Rollback();
     }
}

problemOccurred フラグは、問題が例外にならなかった場合にのみ必要になることに注意してください。この場合、ロールバックは自動的に実行されます。

この実装が使用された理由についてさらに洞察を得ることに興味があります。

更新:これまでの回答のいくつかは、私が説明した実装が使用された場合、try-catch ブロックが必要になると主張していました。これはそうではありません。using ブロック内で例外が処理されない場合、トランザクションは自動的にロールバックされます。これは、既存の実装と私が説明した実装の両方に当てはまります。詳細については、こちらの「トランザクション スコープの完了」セクションを参照してください。

更新 2:回答で説明されていたことをようやく理解しました。これは、言語設計者が適切と考える方法で解釈できる言語構成ではなく、IDisposable パターンの実装です。Complete への呼び出しがなければ、Dispose メソッド内のコードは、using ブロック内のコードが正常に実行された結果として呼び出されたのか、それとも例外が発生したために呼び出されたのかを認識できません。transaction と rollback の両方がキーワードである次のようなものを想像していました。

transaction
{
    /* Perform transactional work here */

     if(problemOccurred)
     {
         rollback;
     }
}

これはもちろん、トランザクション オプションを TransactionScope に渡す必要がある場合に問題を引き起こします。

4

4 に答える 4

3

@Jon Skeetが言うように、成功のために書くコードの量は、現在の方法よりも少ない(そして見苦しくない)と思います。ただし、トランザクションの観点からは、悲観的になり、成功が明示的に示されない限りロールバックすると想定する必要があると思います。私の意見では、誤ってトランザクションをコミットすることは、コード エラーのために成功したトランザクションのコミットに誤って失敗するよりも、はるかに悪い問題です。

于 2010-01-04T13:26:47.913 に答える