by shigemk2

当面は技術的なことしか書かない

scalikejdbcのトランザクションとセッションの関係について メモ

結論から言うと、ライブラリの使い方だけじゃなくて、

以下のような処理があったとする。

DB.localTx { implicit session =>
    処理A
    処理B
    処理C
}

こういう書き方をしたら、ブロックの中でトランザクションが働いて、処理A→B→Cの順番に実行されるのだけれど、図1のように処理がうごくことを期待しているのだが、

  1. 処理A成功
  2. 処理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)
}

という、トランザクションとセッションの理解がいい加減だと、トラブルに見舞われてしまう、という話でした。。。

図1 https://files.gitter.im/scalikejdbc/ja/AKEG/image1.JPG

図2 https://files.gitter.im/scalikejdbc/ja/yUFe/image2.JPG