MyBatisで行ロック(悲観ロック)を行うには?

提供: tknotebook
2016年11月19日 (土) 10:31時点におけるNakamuri (トーク | 投稿記録)による版

(差分) ←前の版 | 最新版 (差分) | 次の版→ (差分)
移動: 案内検索

メインページ>コンピュータの部屋#Java>MyBatis Tips

悲観ロックは単純にやってもうまくゆかない

テーブルの行を select ・・・ for update で行ロックして update 文で更新するのは SQL の 「悲観ロック」 の常とう手段です。

ただ、MyBatis では selecetステートメント(Mapperインターフェースの select用メソッド)で select ・・・ for update を実行し、 updateステートメント(Mapperインターフェースの update用メソッド)で行を更新してもうまくゆかないことが多いです。

うまくゆかない理由

多くのデータベースの既定のアイソレーションレベルは READ COMMITED です。

READ COMMITEDでは行ロックの寿命はカーソルがその行に留まっている間です、しかし、MyBatis は select ステートメント を実行すると、カーソルも PreparedStatement もクローズしてしまいます。これでは行ロックが残る訳が有りません。

対処法

アイソレーションレベルを REPEATABLE_READ にします。 アイソレーションレベルが REPEATABLE_READ なら、行ロックの寿命はトランザクションの終了(commit/rollback)までです。

アイソレーションレベルは SqlSessionFactory#openSession の引数で指定できます。