SpringBoot @Retryableでリトライがかからない事象にハマった
SpringBoot @Retryableでリトライがかからない事象にハマって時間を消費したので共有
結論
@Retryableアノテーションを付けていても、内部呼び出しだとリトライされない。
以下のような構成で、functionAを外部から叩かれた時、functionBはリトライがかかる想定だったがリトライされなかった。
public void functionA() { this.functionB(); } @Retryable private void functionB() { throw new Exception("例外発生") }
リトライしたければ外から叩かれるメソッドにアノテーションを付ける必要がある。
以下のコードだと想定通りにリトライされる。
@Retryable public void functionA() { this.functionB(); } private void functionB() { throw new Exception("例外発生") }
理由
SpringではDIでインスタンス生成を管理できるが、DIで生成されるインスタンスはSpringの機能で一枚ラップされている。
このラッパーによって、アスペクト思考的な機能が提供されている。
@Retryableもその一つで、ラッパーを通してメソッドが呼び出された時、例外をラッパー側でチェックしていて、必要があれば再度実行してくれる仕組みになっていると思われる。
なので、インスタンス内部間のメソッド呼び出しではラッパーが例外を検知できないので、リトライが効かない、という状況になっていたのだと思われる。