8.10.3 楽観的ロックを使用する際の注意事項
ここでは,楽観的ロックを使用する際の注意事項について説明します。
(1) Versionフィールドの設定時の注意事項
Versionフィールドの設定時の注意事項を次に示します。
-
Versionフィールドが設定されていない場合,そのエンティティに対するバージョンチェックは実施しません。その場合,エンティティとデータベースの間の整合性を保つようなアプリケーションをユーザ責任で作成してください。
-
トランザクションにVersionフィールドが設定されているエンティティと設定されていないエンティティが含まれている場合,Versionフィールドが設定されているエンティティに対してだけバージョンチェックが実行されます。なお,エンティティにバージョンが含まれていないことはトランザクションの決着処理には影響ありません。
-
ユーザはVersionフィールドの値を参照できますが,更新はしないでください。ただし,バルク更新処理ではVersionフィールドの値を更新できます。
(2) lockメソッド使用時の注意
lockメソッド使用時の注意事項を次に示します。
-
Versionフィールド(プロパティ)を持たないエンティティに対するEntityManagerのlockメソッドはサポートしていません。Versionフィールド(プロパティ)を持たないエンティティを指定して,lock(entity, LockModeType.READ)またはlock(entity, LockModeType.WRITE)が呼ばれた場合は,PersistenceExceptionが発生します。
-
Versionフィールド(プロパティ)を持つエンティティの状態が更新される場合は,lockメソッドの呼び出し有無にかかわらず,ダーティリード,および繰り返し不可能な読み込みの現象は発生しません。
-
CJPAプロバイダではLockModeType.READが指定された場合,エンティティに該当するデータベースの値に変更がないかを確認するために,UPDATE文を発行します。このため,データベースに対してUPDATE文による排他が掛かります。UPDATE文は,flush処理の実行時およびトランザクションのコミット時に発行されます。エンティティオブジェクトの状態に変更がない場合でも発行されます。ただし,エンティティが削除された場合は発行されません。
(3) HiRDBでのクライアント単位の排他制御について
CJPAプロバイダの楽観的ロックは,データベースのIsolationレベルがRead Committedでアクセスされることを想定したロック方式です。データベースがHiRDBの場合,Isolationレベルがデフォルトの設定ではRepeatable Readであるため,Read Committedに変更する必要があります。
クライアント単位のIsolationレベルは,クライアント環境変数のデータ保証レベルのPDISLLVLパラメタで設定します。デフォルトの値はRepeatable Read (2)です。このため,Read Committed (1) に変更してください。変更例を次に示します。
変更例:PDISLLVL=1
クライアント環境変数はConnector属性ファイルの<config-property>タグでenvironmentVariablesプロパティの値に指定するか,またはHiRDBのクライアント環境変数グループの設定ファイルに追加してください。
クライアント環境変数のデータ保証レベルをデフォルト設定のRepeatable Readで動作させた場合は,共有モードで排他が掛かります。このため,findメソッドなどの参照系SQLの発行とflushメソッドなどの更新系SQLの発行を組み合わせることによって,デッドロックが発生しやすくなるので注意してください。