結論から言うと、ライブラリの使い方だけじゃなくて、
以下のような処理があったとする。
DB.localTx { implicit session =>
処理A
処理B
処理C
}
こういう書き方をしたら、ブロックの中でトランザクションが働いて、処理A→B→Cの順番に実行されるのだけれど、図1のように処理がうごくことを期待しているのだが、
- 処理A成功
- 処理B失敗
の場合、処理Aがロールバックされない。それは処理Aをこういうふうに書く場合だ。
def 処理A(a: Int, b: String)(implicit session: DBSession = AutoSession) = { // 処理 }
普通にこのように書いてしまうと、処理AのセッションはAutoSessionあつかい(暗黙の引数で省略されているから)となってしまい、処理Aが失敗したらそこでセッションが切れてコミットされてしまう。(図2参照)
DB.localTx { implicit session =>
処理A
処理B
処理C
}
なので、このように書いて、sessionの種類を明示しなければならない。
DB.localTx { implicit session =>
処理A(session)
処理B(session)
処理C(session)
}
という、トランザクションとセッションの理解がいい加減だと、トラブルに見舞われてしまう、という話でした。。。