Cosminexus V9 アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)

[目次][用語][索引][前へ][次へ]

6.7.4 キャッシュ機能を使用するときの注意事項

ここでは,エンティティオブジェクトのキャッシュ機能を使用するときの注意事項を説明します。

<この項の構成>
(1) クエリでデータを更新または削除した場合の注意
(2) キャッシュを使用する永続化コンテキストが複数ある場合の注意
(3) キャッシュの登録および更新タイミングに関する注意事項

(1) クエリでデータを更新または削除した場合の注意

アプリケーション内でJPQLやネイティブクエリを使用して,データを更新したり,削除したりした場合,キャッシュの内容は更新されません。refresh操作などを行って,データベースの内容を取得し直してください。

次に示す操作の場合,キャッシュのデータを読み込むため,データベースへの更新がされません。

  1. データをエンティティオブジェクトに読み込む。
    キャッシュにもエンティティのデータが登録されます。
  2. 1.で読み込んだデータを含む削除クエリを実行する。
    削除クエリの実行でデータは削除されますが,キャッシュは削除されません。
  3. 1.と同じデータをエンティティオブジェクトに読み込む。
    1.と同じデータのため,キャッシュにあるデータを読み込みます。
  4. 3.のデータをflushする。
    データベースには該当する行がないため,追加または更新処理ができません。

(2) キャッシュを使用する永続化コンテキストが複数ある場合の注意

キャッシュを使用することで,データベースへのアクセス頻度を下げることができます。ただし,一方でキャッシュによるデータのタイムラグが発生して,楽観的ロック例外の発生頻度が高くなるおそれもあります。

キャッシュは永続化コンテキスト単位に存在します。そのため,永続化コンテキストと対で存在するEntityManagerが複数かつ同時期に生成され,同一プライマリキーのエンティティを同時に操作すると,一方でデータを更新しても他方でタイミング良く,更新後のデータを参照できないことがあります。これによって,楽観的ロック例外が発生しやすくなります。

次に,楽観的ロック例外が発生する仕組みと対処方法について説明します。

(a) 楽観的ロック例外が発生する例

ここでは,次の図に示す環境で,永続化コンテキスト単位にキャッシュが存在する場合を例に説明します。

図6-19 この例で説明する環境

[図データ]

図の状態では,キャッシュとデータベースには不整合はなく,すでにキャッシュにAというデータが格納されているものとします。

  1. 永続化コンテキスト1でデータをAからBに変更します。
    このとき,キャッシュとデータベースの内容が等しいため例外は発生しません。

    図6-20 永続化コンテキスト1でのデータの変更

    [図データ]

  2. 1.の処理が終了後,永続化コンテキスト2でAのデータを変更します。
    キャッシュのデータは変更されていないため,データベースのデータとキャッシュに不整合があります。このため,楽観的ロックによる例外が発生します。

    図6-21 永続化コンテキスト2でのデータの変更

    [図データ]

このような環境の場合,キャッシュを使用すると,更新されないキャッシュが残ってしまい,楽観的ロックによる例外が発生することがあります。

(b) 対処方法

楽観的ロック例外が発生した場合は,キャッシュ内の該当オブジェクトは削除されます。このため,findメソッドを実行するか,またはrefreshメソッドを実行して関連するすべてのデータを再度データベースから取得してください。これによって,キャッシュのデータとデータベースを同期できます。

(3) キャッシュの登録および更新タイミングに関する注意事項