0

iBatis と Spring を使用して、1 つ以上のテーブルに対する複数のDB 操作を含むトランザクションを実現するにはどうすればよいですか?

詳細に説明しましょう:
マスターと詳細の関係を持つ 2 つのテーブル A と B があります。[単一データベース内の両方のテーブル]。

/* テーブル A: */

a_id [主キー]
[およびその他の列]

/* 表 B: */

b_id [Primary Key]  
a_id [Foreign Key = PK of table A]  
[plus other columns]  

私の Dao には次のメソッドがあります (DB 操作を実行するために iBatis sqlMap を使用しています)。

insertA();  
insertB();  
updateA();  
updateB();  
deleteA();  
deleteB();  

上記の各操作はアトミックです (& はクライアントから呼び出され、Spring/iBatis を介してデータベースにコミットされます)。

この時点まで、すべて正常に動作します。[つまり、各テーブルでINDIVIDUALの挿入/更新/削除を実行できます。]

-- 次に、上記の DB 操作の 2 つの組み合わせを ATOMIC 操作として実行する必要があります。
SVCレイヤーから達成したいことは次のとおりです。

start Tranaction  
    operation on Table-A (via method of Dao class) - op #1  
    operation on Table-B (via method of Dao class) - op #2  
end Transaction  

例1:

start Tranaction  
    insertA();  
    insertB();  
end Transaction  

例 2:

start Tranaction  
    updateA();  
    updateB();  
end Transaction  

ここで、op#2 が失敗した場合、op#1 もロールバックされるようにします。つまり、完全なロールバック。

そこで、上記の DAO メソッドを呼び出す Service レイヤー内に追加のメソッドを作成しました。(Svc) コードを実行する前に、手動で [cmd-line を介して] データベースのデータを変更し、DB 制約のために 2 番目の操作が失敗するようにしました。

ここで、op #2 [Table-B] は失敗しますが、op #1 は DB でコミットされます。つまり、完全なロールバックはなく、部分的なロールバックのみです。

操作 #2 が失敗した場合、操作 #1 もロールバックするべきではありませんか?

ApplicationContext.xml で使用しているものは次のとおりです。

  • 「DataSourceTransactionManager」[Spring] トランザクション用。
  • iBatis 2.3.x [SqlMapClient]
  • スプリング 3.0
  • DefaultAutoCommit は FALSE に設定されています。
  • "tx:method" 内: [ATOMIC 操作が実行されるサービス メソッド)
    Propagation="REQUIRED" [他の値でも試しましたが、使用しませんでした]
    rollback-for=Exception-Name-for-which-to-rollback

他に何かしなければならないことはありますか?
私は何か間違ったことをしていますか?
これは正しい方法ですか、それともより良いオプションがありますか?

4

1 に答える 1

0

<

私の意見では、データの整合性を考慮する必要があります。操作 #2 でシステムのデータの整合性が失われる場合は、操作 #1 に従ってロールバックする必要があります。

目的を達成するには、次のように、try/catch ブロックで op #1 と #2、wrapper #2 を呼び出すだけです。

try {

    start Tranaction ;
    //pkA is primary key of A
    Object pkA = insertA();  
    updateA(pkA);  

    try {
        Object pkB = insertB(pkA); 
        updateB(pkB);  
    }
    catch(Exception e) {
        logger.ERROR("Error when inserting and updating B.Ignore. ",e);
    }
    commit transaction;
}
catch(Exception e) {
   logger.ERROR(e);
   rollback Transaction;
}

HTH。

于 2012-06-26T07:47:48.587 に答える