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句」を使うと書いてあります。
- http://www.apple.com/jp/webobjects/wo_docs_j.html
- http://developer.apple.com/documentation/WebObjects/Reference/API/com/webobjects/eoaccess/EODatabaseContext.html
- http://developer.apple.com/documentation/WebObjects/Enterprise_Objects/UpdateStrategies/chapter_9_section_3.html
Inverse Pages: オプティミスティックロック