Hitachi

Cosminexus V11 アプリケーションサーバ 機能解説 互換編


8.10.1 楽観的ロックの処理

楽観的ロックを使用すると,CJPAプロバイダはデータベースのデータがほかのアプリケーションから更新されていないかをユーザに代わってチェックします。データベースのデータが更新されていると,CJPAプロバイダは例外を発生させて,ユーザにデータが更新されていることを通知します。また,トランザクションをロールバックにマークします。

〈この項の構成〉

(1) データ更新の有無のチェック方法

データが更新されているかどうかは,データベースのテーブル上に用意したバージョン列の更新の有無によってチェックします。データベース上のデータが更新されると,バージョン列のバージョン番号が更新されます。これによって,ほかのアプリケーションなどからデータベースが更新されたことがわかります。データベースを更新するときのバージョン列の状態と動作について次の表に示します。

表8‒17 データベースを更新するときのバージョン列の状態と動作

テーブルのバージョン列の状態

動作

バージョン列の値が更新されていない場合

CJPAプロバイダは,エンティティの情報をデータベースに反映します。このとき,データベースのバージョン列の値を更新します。

バージョン列の値が更新されている場合

ほかのアプリケーションなどからデータベースのデータが更新されていることを表します。このため,CJPAプロバイダはOptimisticLockExceptionを発生させて,トランザクションをロールバックにマークします。

このように,バージョン列の状態によって,エンティティを読み込んだ状態からデータベースを更新するまでに,ほかのトランザクションがデータを更新していないことを保証できます。

(2) 永続化フィールドおよびリレーションシップのバージョンチェック

楽観的ロックを使用するには,エンティティの永続化フィールドおよびリレーションシップの両方をバージョンチェックの対象にします。バージョンチェックの対象とするには,エンティティにバージョン列に対応するVersionフィールド(プロパティ)を設定してください。Versionフィールドは@VersionまたはO/Rマッピングファイルの<version>タグを使用して設定します。

エンティティのバージョンチェックは次のどちらかのタイミングで実行されます。

バージョンチェックによってエンティティのバージョンが古いことが判明した場合,OptimisticLockExceptionが発生します。また,トランザクションはロールバックにマークされます。

(3) flush操作またはトランザクションの決着時のバージョンチェック

エンティティをflush操作またはトランザクションの決着時にバージョンチェックの対象にできます。バージョンチェックの対象とするには,EntityManagerのlockメソッドにエンティティを指定します。EntityManagerのlockメソッドを使用することで,トランザクションでのバージョンチェック対象にエンティティを追加したり,バージョン列の更新方針を変更したりできます。

CJPAプロバイダでは,バージョン列の更新タイミング(lockメソッドのLockModeType)としてLockModeType.READおよびLockModeType.WRITEの二つをサポートしています。バージョン列の更新タイミングの指定内容にかかわらず,CJPAプロバイダではトランザクションの決着時に次に示す二つの事象が起きないことを保証します。

LockModeTypeとしてLockModeType.WRITEを指定すると,エンティティの状態変更がない場合でもバージョン列は強制的に更新されます。バージョン列の更新はflushまたはトランザクションのコミットが呼び出されたタイミングで実行されます。なお,バージョン列の更新前にエンティティが削除された場合,バージョン列の更新は省略されることもあります。