Grailsを扱っていると、データベースのトランザクション処理は、目に見えないところに隠蔽されている。
これって、本当にロールバックされるの?と疑問に思ったりする。
BackgroundThread プラグインを扱って、さらに、その疑問がひっかかったので、ちょっと、調べてみた。
Grailsでは、Service で、
boolean transactional = true
としてやると、データベースへの更新が一つでも失敗すると、そのトランザクションは、ロールバックするとされている。
このデータベースの更新の失敗というのは、どんなものか。
どうやら、この判別は、GrailsRuntimeExceptionが発生した時らしい。
しかも、そのExceptionが画面に表示されないといけない。
つまり、不用意に深い処理の階層で、try/catchして、このGrailsRuntimeExceptionが吸収されてしまうと、ロールバックしないのだ。
GrailsRuntimeExceptionを含むExceptionをcatchしたら、確実に、Exceptionをthrowsして、上位に渡して、最終的にGrailsRuntimeExceptionを画面に表示(error.gspを表示)発生させなければならない。
では、BackgrounThreadプラグインを使った場合は、どうなるのか?
別スレッドだから、画面に表示させることはできないわけだけど、用は、バックグラウンドスレッドとして呼び出されたクロージャーがGrailsRuntimeExceptionを受け取ればよい。
実際にいろいろと、試してみて確認してみたところ、GrailsRuntimeExceptionがあると、ちゃんとロールバックされた。ちょっと、安心。
不用意なtry/catchは、やめましょう。ということで。
もちろん、withTransactionとかあって、ロールバックをコントロールできるみたいだけど、さくさく作っている場合は、こういったことを踏まえておけば、いいかな。