オブジェクトのロック
2007/03/30 (Fri) 22:07:46 JST
オブジェクト (eo) をロックする目的は、オブジェクトに対応するデータベースレコードと同期することです。スレッドのロックのように実行権限を与えるものではなく、 ?EOEnterpriseObject に lock()
, unlock()
のメソッドもありません。
また、データベース行に対応するオブジェクトはオブジェクトグラフの数だけ存在しますが、このオブジェクト間の編集権限を制御するのもロックの目的ではありません。
EOFのロックの戦略
ドキュメントに書かれている3種類のロックの戦略が、オブジェクトに対するロックです。どのロックも目的、方法、効果が異なります。特にロックの効果はデータベースに依存するので注意が必要です。
ドキュメントで使われている用語は、あくまでEOFの仕様としての用法であることに注意してください。DBMSで使われる同じ用語として考えると混乱します。
オプティミスティックロック
オブジェクトの保存時に発行するSQLのWHERE句に、スナップショットの値を指定します。アプリケーションインスタンスがキャッシュしているレコードとデータベースの内容が異なると更新に失敗し、例外を投げます。
このロックの目的は、他インスタンスなどからデータベースが操作されたかどうかを検出することです。同一・他インスタンスからのデータベースの操作を防ぐ手段ではありません。
ペシミスティックロック
オブジェクトのフェッチ時にSELECT FOR UPDATE文を発行し、他トランザクションからの更新をブロックします。他トランザクションからこのレコードに対してSELECT FOR UPDATE文を発行すると (オブジェクトをフェッチすると) 、ロックしたトランザクションが終了するまで待ちます。
このロックの目的は、オブジェクトの保存を保証することです。最も強固と言えば強固なロックですが、待ち状態やデッドロックを起こしやすく、不特定多数のアクセスが予期されるWebアプリケーションには向きません。
また、WebObjectsの実装の問題もあります。フェッチ時にSELECT FOR UPDATE文が発行されることは発行されますが、トランザクションがフェッチで終了してしまいます。フェッチ時のトランザクションと保存時のトランザクションが異なるため、この実装では確実な処理ができません。
オンデマンドロック
上記のロックを組み合わせる方法で、基本はオプティミスティックロック、必要ならオブジェクトを個別にペシミスティックロックでロックします。どちらのロックにも問題があるため、使う意味はあまりないと思います。
Inverse Pages: EODelegateSaving ロックについて