EOOLConflict

2007/03/30 (Fri) 22:07:46 JST

競合の検出

オプティミスティックロックの目的は更新の競合を検出・処理することです。 上記で SELECT ... FOR UPDATE によるロックを挙げましたが、EOFでも最終的にはSQLレベルで競合を検出します。

EOFの更新処理には次の要素が関わっています。

EOFはオブジェクトをフェッチしたときのデータ行をスナップショットとして保持しています。 更新時にスナップショットの内容をUPDATE文のWHERE句に指定することで、データベースに変更があったかどうかを検出します。 もしUPDATEが失敗すれば、他インスタンスまたはアプリケーションからデータベースを変更されたことになります。

生成されるUPDATE文

WHERE句に含まれるのは主キーの属性とロックを指定した(EOModelerで鍵マークにチェックした)属性です。 例えばMovieエンティティはcategory属性のみをロックするものとし、次のデータを持つオブジェクトをフェッチするとします。

MOVIE_ID = 1
CATEGORY = "Action"

category属性の値を "Drama" に変更して更新すると、次のようなSQL文が生成されます。 WHERE句に含まれる属性値は変更前の値、つまりスナップショットです。

UPDATE MOVIE SET CATEGORY = "Drama"
   WHERE (MOVIE_ID = 1 AND CATEGORY = "Action")

WebObjects 5以前の検出方法

更新前にオブジェクトに対応するデータ行を取得してスナップショットと比較します。 もしデータ行とスナップショットの内容が異なるならば他アプリケーションから更新があったとみなされ、例外が発生するようです(4.xも使える環境もないので確認はしていません)。

WebObjects 4.xの日本語ドキュメントにはもちろん、5.2のAPIリファレンスにもこのように書いてありますが、5.2のEnterprise Objects には「UPDATE文のWHERE句」を使うと書いてあります。


Inverse Pages: オプティミスティックロック