blog

[AOP] トランザクション制御と、同じクラス内のメソッド同士が呼び合う場合のアノテーションスライシングの落とし穴

最近、タイトルの状況に遭遇し、具体的には次のとおりです:インターフェイスInterfaceがあり、2つのメソッドA()、B()を提供し、抽象クラスAbstractは、Aメソッドを実装し、Aメソッドが内...

Apr 5, 2020 · 3 min. read
シェア

同じクラスのメソッドがお互いを呼び出すとき、呼び出されたメソッドのアノテーションはスライスに取り込まれないので、内部的に呼び出されたメソッドのアノテーションは無効になります。

最近、タイトルの状況に遭遇し、具体的には次のとおりです:インターフェイスInterfaceがあり、2つのメソッドA()、B()を提供し、抽象クラスAbstractは、Aメソッドを実装し、Aメソッドは、内部的にBメソッドを呼び出し、クラスImplの実装はAbstractを継承し、B()を実装し、クラス構造です。Aメソッドは主に状態のライトバックを実装し、Bメソッドはロジックを実装しているため、Bメソッドのトランザクションをロールバックし、AメソッドはBメソッドの実行を正しく読み取り、実際の結果に応じてトランザクションを保存できることが望まれるため、A、Bともに@Transactionアノテーションを使用し、Bメソッドでは

propagation = Propagation.obj;

メソッド A は try{}catch() ブロックを使用して B の例外を処理し、B のトランザクションを A のライトバックから独立させます。

しかし、実際の処理では、メソッドBで例外が発生し、先頭に向かって投げられると、メソッドAも書き戻して例外を報告しました:

Transaction rolled back because it has been marked as rollback-only

この例外は、通常、トランザクションの入れ子で発生し、トランザクションの内部部分が例外を処理しないため、try/catchと例外の外部部分が、例外の上位メソッドに返された場合でも、内部トランザクションがコミットされます/ロールバック、外部トランザクションの一部であることが判明するので、ここでコミットまたはロールバックされませんが、統一されたに対処するために外部トランザクションに転送されます。外部トランザクションは、トランザクション内で例外が発生し、ロールバックする必要があることを識別するロールバック専用フラグでマークされ、外部トランザクションがコミットされる準備ができたら、フラグが見つかり、ロールバックされ、エラーメッセージが出力されます。

具体的なコード



ロールバック操作はコミット操作によって引き起こされます:





上記のメソッドはいずれもトランザクションの終了時にトリガーされます:





このメソッドは、aop が @transaction を検出したときに呼び出されるエントリメソッドです。アノテートされたメソッドは、エントリーの前にこのロジックをトリガーし、設定に応じてロールバックとコミットのコンテキストに savePoint を設定します。

コードのロジックによると、Bメソッドはコミット時にロールバックを引き起こしますが、コンフィギュレーションはREQUEIRS_NEWタグであり、Bトランザクションは

if (status.isNewTransaction())

A以外のトランザクションに影響を与えることなく直接ロールバックされるので、トランザクションエントリーのメソッドをデバッグして確認してください。



その結果、メソッドAが呼び出されたとき、aopスライスにまったく捕捉されていないことが判明しました。

別の数セットのテストが行われ、発見されました。これがエラーの原因ですが、以前は、呼び出し側がトランザクションアノテーションを持っていない場合、内部呼び出しは、呼び出された側のトランザクションアノテーションが無効であることを知っているだけで、状況はこれに限定されないようです。

そのため、ロジックの一部でトランザクションが必要だと判断された場合は、外部メソッド呼び出しのみを許可するという制限を設けて設計するのがベストです。内部呼び出しはクリーンで良いですが、注意が必要です!



Read next

JS徹底解説:型変換編

型付きの弱い言語であるjsの型は、特に型変換をはじめ、常に頭を悩ませてきました。 あなたは、結果がToNumberへの呼び出しの値であることを見ることができ、その後、この中に呼び出され、その後、これは何ですか?彼は実際に入力値が元の値に変換され、まず第一に、元の値の間の変換は、その後、彼です...

Apr 5, 2020 · 8 min read