8.11 JPQLでの悲観的ロック
悲観的ロックとは,複数のトランザクションによってデータベース上の同じレコードを更新するときに,対象となるレコードを占有ロックする方法です。あるトランザクションがあるレコードに対して悲観的ロックを掛けると,ほかのトランザクションはそのレコードを参照または更新できません(ただし,Oracleの場合,参照はできます)。悲観的ロックはJPQLを使用しているときだけ使用できます。
悲観的ロックを使用すると,ロックを取得したトランザクションが終了するまでロックの解放待ちが発生します。このため,楽観的ロックよりも同時実行性はありませんが,楽観的ロックで発生するトランザクションのコミット時のエラーを回避できます。
- 悲観的ロックの指定方法
-
悲観的ロックは,CJPAプロバイダがサポートするクエリヒントを利用することで実現します。悲観的ロックは,QueryメソッドのsetHint()メソッドまたは@NamedQueryの属性に@QueryHintを指定して実行します。
- 悲観的ロック機能の実装例
-
悲観的ロック機能の実装例を次に示します。
- 実装例1
-
QueryメソッドのsetHint()メソッドで悲観的ロックを指定する場合の例を次に示します。
Query query = manager.createQuery("SELECT emp FROM Employee AS emp"); query.setHint("cosminexus.jpa.pessimistic-lock","Lock");
- 実装例2
-
@NamedQueryの属性の@QueryHintで悲観的ロックを指定する場合の例を次に示します。
@NamedQuery( name="employee_list", query="SELECT emp FROM Employee AS emp", hints={ @QueryHint(name="cosminexus.jpa.pessimistic-lock", value="Lock") } ) @Entity public class Employee{ ・・・ }
- 注意事項
-
悲観的ロックが使用できるのはJPQLの時だけです。createNativeQueryメソッドや@NamedNativeQueryのhints属性に@QueryHintを指定しても有効にはなりません。また,O/Rマッピングファイルの<named-native-query>タグのhint属性に指定した場合も有効にはなりません。なお,CJPAプロバイダでの悲観的ロックの排他仕様は,使用するデータベースの仕様に準じます。