0

私のクラスは次のように定義されています

@Transactional
@Service
public class InteractionHistoryServiceImpl implements InteractionHistoryService {

クラス内には、次のように個別の DB2 ストアド プロシージャに対して 4 つの個別の呼び出しを行う単一のメソッドがあります (疑似)。

@Override
public void createInteractionHistory(String userId, String userChannel,
        CreateInteractionHistoryRequestPayload requestPayload) {

dao.createInteractionHistory(userId, userChannel, viewableBy,
            interactCode, systemCreationDateTime, partyGrpId,
            interactionHistoryController);

dao.createInteractionHistoryDetails(userId, interactonDescription, interactionHistoryController);

dao.createInteractionHistoryDetailsLink(userId, componentId, objectId, objectType, correspondanceType, direction, interactionHistoryController);

dao.createInteractionHistoryDetailsLink(userId, componentId, documentId, DOCUMENT, correspondenceType, direction, interactionHistoryController);
}

ここで、最後の呼び出しで、大きすぎるフィールド幅を渡すことでデータベースに例外を強制するため、proc をまったく呼び出すことができません。これはキャプチャされ、RuntimeException を拡張するシステム例外に変換されます。

例外の後にこのコードをデバッグしたところ、Spring フレームワークにフィードされ、ロールバックしているように見えます。

基になるテーブルを確認すると、以前のすべてのストアド プロシージャが成功し、ロールバックされていないことがわかりますが、最後の呼び出しは成功しませんでした。

これにより、一貫性のないデータと頭痛が残ります。私の理解では、これらはコミット/ロールバックをすべてまたはまったく処理する必要があるということです。

ストアド プロシージャを確認しましたが、データベースでコミットが行われていません。

ここに何かアイデアはありますか?

4

1 に答える 1

1

トランザクションの境界を考慮する必要があります。トランザクション境界は通常、BEGIN TRANSACTION および COMMIT / ROLLBACK ステートメントが実行される場所であり、完全に Spring 次第ではありませんが、データベースの実装に依存する可能性もあります。

クラス レベルで @Transactional を指定すると、クラスのすべてのパブリック メソッドに宣言的なトランザクション境界があることを示します (つまり、メソッドが実行される前にトランザクションが開始され、メソッドが終了するとコミットされ、例外が発生するとロールバックされます)。

あなたの場合、4 つのcreateInteractionHistory呼び出しを 1 つのトランザクションに含めていないようです。代わりに、4 つの個別のトランザクションです。したがって、最後の 1 つが失敗した場合、最初の 3 つがすでに成功しています。

ただし、これら 4 つの呼び出しをすべて 1 つのトランザクションに含めたとしても、すべての SQL が 1 つのトランザクションで実行されるとは限りません。これは、ストアド プロシージャ内にあるコードと、DB2 がトランザクション境界を描画する方法に依存するためです。

Spring のトランザクション境界と伝播のトピック、そして DB2 トランザクションにも時間を費やすことをお勧めします。スプリング マニュアルの第 11 章が参考になります。

于 2013-01-23T03:56:49.207 に答える