web-dev-qa-db-ja.com

1つのトランザクションで2つのDAOメソッドを管理する方法は?

インタビューで誰かが私に尋ねました:1つのトランザクションで2つのトランザクション/ daoメソッドをどのように管理しますか?必要な機能:

  1. それらのいずれかが失敗した場合、両方の方法をロールバックする必要があります。
  2. どちらのメソッドも、1つのトランザクションでアタッチして個別に呼び出すことができます。
  3. 管理は、サービス層ではなくDAO層で行う必要があります。

質問は、春のトランザクション管理に関連しています。

12
Satish Pandey

まず、トランザクション管理はDAOレイヤーではなくサービスレイヤーで行う必要があります(適切なトランザクション分離レベルとさまざまな方法での伝達を処理するため)パフォーマンスのオーバーヘッドが大きくなるためです。また、作業単位のスコープは、データアクセスレイヤーではなくサービスレイヤーから取得されます:2つ以上のDAOを処理する必要があるビジネスプロセスの実行を想像してください。

インターネットでは、その方向を herehere および here として指摘する多くの議論があります。

とにかく、面接なので質問はそのまま受け入れましょう。私の観点からは、@Transactionalアノテーション(またはXML構成)と、REQUIRED値を使用したトランザクション伝達の両方のメソッド。このようにして、これらのメソッドのいずれかが呼び出され、前のトランザクションが存在しない場合、新しいトランザクションが作成されます。

@Transactional
class MyDAO {

   @Transactional(propagation = REQUIRED)
   public void foo() {
   }

   @Transactional(propagation = REQUIRED)
   public void bar() {
   }

}
12

私の答えで春とフレームワークを無視しています.....関数パラメーターを使用する基本的なアイデアです。このコンセプトは[ここにフレームワークを挿入]にも適用できると思います。

2つのDAOメソッドの外でコミット/ロールバックを処理する必要があります。 2つのメソッドは、トランザクション/接続を入力として受け取る必要があります。

擬似コード:

bool method1(Tran t) { /* stuff */}
bool method2(Tran t) { /* stuff */ }

callingMethod() {
     Tran t = null;
     try {
         t = new Conn().open().startTran();
         if(method1(t) && method2(t))
             t.commit();
         else
             t.rollBaack();
     }
     catch(ex) {  t.rollBack();  }
     finally {  t.closeConn();  }
}
2
mike30

2つのメソッドが独立して機能すると同時に、同じトランザクションで実行される可能性があるため、Propagation-Requiredを使用する必要があります。トランザクションを同じトランザクションで実行する必要がある場合は、最初のトランザクションを使用します。それ以外の場合、独立して呼び出されると、新しいトランザクションが作成されます。私が間違っていたら訂正してください。

0
M Anil Kumar