Edited at

悲観ロックと楽観ロック

■悲観ロック

・更新処理の頻度が高い場合に採用する。

・SELECT ~ FOR UPDATEなどをかける。

・DB側でロックをかける。

・あらかじめロックをかけておこうの精神


■楽観ロック

・更新処理の頻度が低い場合に採用する。

・DBでなく、アプリケーション側(O/Rマッパーなど)で排他処理を行う。

・とりあえず更新してみてダメだったらやり直そうの精神

・リードアンコミテッドは防げるが、アンリピータブル/ファンタオムは防げない。

1.更新対象エンティティのバージョンを取得する。

2.エンティティの更新処理を完了させる。

  UPDATE  T

  SET    T.VERSION = VERSION + 1

  WHERE  T.VERSION = VERSION

3.バージョンが変更されているかどうか判定

 (更新結果が0件かどうかで判定する。)

 3-1.変更なし

  バージョンをあげてコミットする。

 3-2.変更あり

  トランザクションをロールバックする。


■DBFluteでの排他処理 (更新時)

メソッドによって使い分ける。

楽観的ロック : update()


排他的ロック : updateNonstrict() などなど

第三者が

 更新済み : 「EntityAlreadyUpdatedException」発生

 削除済み : 「EntityAlreadyDeletedException」発生

■DBFluteでどのカラムをバージョン情報とみなすか。

・カラム名が「VERSION_NO」の場合、自動でそれを採用する。

・それ以外の場合、設定ファイルの編集が必要。

 littleAdjustmentMap.dfprop

  -> optimisticLockMap

   -> versionNoFieldName = カラム名

■DBFluteでの排他処理 (検索時)

一覧画面で取得したデータが詳細画面表示時に削除されてしまった場合

selectEntityWithDeletedCheck() などでチェックができ

削除済みの場合、例外「EntityAlreadyDeletedException」が発生する。


■参考

https://seroku.jp/wp/アプリケーション開発におけるロックの重要性と-2/

(楽観ロックのイメージ図 : ロストアップデート状態となる楽観的ロック使用時)

http://dbflute.seasar.org/ja/manual/function/genbafit/implfit/exclusivecontrol/index.html

(DBFluteの楽観的ロックの説明)

http://dbflute.seasar.org/ja/manual/function/ormapper/behavior/update/update.html

(DBFluteの更新処理について)