10

Spring IoCおよび JDBC Template クラスを使用する Java アプリに取り組んでいます。m1() から m4() までの 4 つのメソッドを持つ DAO クラスがあります。m1 はテーブル t1 で複数の挿入と更新を実行し、m2 はテーブル t2 で、m3 は t3 で、というように実行します。

DAO メソッドは次のように使用されます。

while(true)
{
  //process & generate data

  dao.m1(data1);
  dao.m2(data2);
  dao.m3(data3);
  dao.m4(data4);

  //sleep
}

4 つの連続するメソッド呼び出しでの db 操作をアトミックにする必要があります。4 つのテーブルすべてが正常に更新されるか、まったく更新されません。したがって、m3() で操作を実行中にエラーが発生した場合、m2 と m1 で実行されたすべての変更 (更新と挿入) をロールバックしたいと考えています。

それで、春はあなたに次のようにさせますか?

while (true)
{
  //process & generate data

  transaction = TransactionManager.createNewTransaction();

  transaction.start()

  try
  {
    dao.m1(data1);
    dao.m2(data2);
    dao.m3(data3);
    dao.m4(data4);
  }
  catch(DbUpdateException e)
  {
    transaction.rollBack();
  }

  transaction.end();

  // sleep

}

またはそれを行うより良い方法はありますか?

4

4 に答える 4

15

はい、Spring を使用すると、トランザクションをプログラムで制御できます。

個人的には、次のようなアノテーションを使用した宣言型トランザクションを好みます。

public void runBatchJob() {
  while (true) {
    // generate work
    doWork(unitOfWork);
  }
}

@Transactional
private void doWork(UnitOfWork work) {
  dao.m1(data1);
  dao.m2(data2);
  dao.m3(data3);
  dao.m4(data4);
}

DAO 関数が定義されている場所:

@Transactional
public void m1(Data data) {
  ...
}

これには、applicationContext.xmlに次のものが必要です。

<tx:annotation-driven/>

宣言型トランザクションは、トランザクションの要求、新しいトランザクションの要求、トランザクションのサポートなどを宣言できます。 で注釈が付けられたブロックが を@Transactionalスローすると、ロールバックが発生しRuntimeExceptionます。

于 2009-06-21T13:41:31.717 に答える
8

完全を期すために、プログラムによる解決策は次のようになります。

private TransactionTemplate transactionTemplate;

public setTransactionManager(PlatformTransactionManager transactionManager) {
  this.transactionTemplate = new TransactionTemplate(transactionManager);
}

...

while (true) {

  transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(TransactionStatus status) {
      try {
        dao.m1(data1);
        dao.m2(data2);
        dao.m3(data3);
        dao.m4(data4);
      } catch(DbUpdateException e) {
        status.setRollbackOnly();
      }
    }
  });
}
于 2009-06-21T15:13:22.733 に答える
1

はい、これらの呼び出しをメソッド内に配置して、トランザクションを宣言的に指定できます。

そのコードを追加する必要はありません。Spring が追加してくれます。

于 2009-06-21T13:39:52.470 に答える
1

Spring は、説明したように @Transactional を使用するか、必要に応じて XML を使用することで、これをすべて処理できます。

正しく取得するための重要なことは、 必要なトランザクション伝播のタイプであり、すべてアプリケーションに依存します。

デフォルトでは、トランザクションが存在しない場合は開始され、すでに開始されている場合は既存のトランザクションを再利用します。これは、4 つの DAO をすべてアトミックにしたい場合に必要な動作です。

(MyService) と呼ばれる DAO メソッドを管理するクラスに @Transactional を配置します。このレイヤーの下にあるものはすべて、そのトランザクション境界に参加します。

すなわち:

@Transactional
public void m1(Data data) {
 ...
}

@Transactional
public void m2(Data data) {
 ...
}

コードでこれを行うことは完全に不要です。

詳しくはこちら

于 2009-06-22T09:18:07.630 に答える