Hibernateで嵌った続き。
前回はService層でupdate→select→updateという処理を流した所selectで落ちてたと言うお話。
ひとまずこの問題は解決したのだがよくよくDBを見てるとおかしなことが。
何故か1回目のupdateの結果でデータが更新されている。
Serviceで例外が発生した場合は全てrollbackされると聞いていたのだが、何度テストしなおしてもcomimtされているみたい。
どういうことなのかと先行チームに聞いてみるも原因がわからない。
しかしよくよく話を聞いてみると、どうやらSQLExceptionをthrowしてテストしたときはrollbackしたので大丈夫だといこうとらしい。
なんでそれですべての例外がrollbackされることになってるんだというかそれでテストしたことになってるのかよとか思ったのだがとりあえず後回し。
実際にSQLExceptionで落とすと確かにrollbackされる。
もしかして…と思いRuntimeExceptionとExceptionで試してみると予想通り前者はrollback、後者はcommitされた。
そのとき自分が使っていた例外は、社内FWの「データがあるはずなのに1件も取れなかったException」だった。
確証が欲しかったのでリファレンスを読んでみると
However, please note that the Spring Framework's transaction infrastructure code will, by default, only mark a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. (Errors will also - by default - result in a rollback.) Checked exceptions that are thrown from a transactional method will not result in the transaction being rolled back.
とちゃんと書いてある。
最初からそんくらい読んどけって言われそうだが、そもそもこの文書を読んだのが社内では自分が初めてだったり。
何故か社内の人たち英語のreferenceとか読まないのですよ。自分だって超苦手な英文頑張って読んでるのに。
結局このときは「データがあるはずなのに1件も取れなかったException」をRuntimeExceptionを継承することで問題を解消した。
この後にも何かあった気がするのだけど、もっと別のところで山積みの問題があって忘れてしまった。
もういい加減「よくわからないけどこうしたらできた」的な作り方はやめてほしい…