私は記事 Java Persistence 2. のロックと同時実行性)を読み、サンプルアプリケーションを実行しました。しかし、PESSIMISTIC_READとPESSIMISTIC_WRITEの違いを理解できません。コードを変更します。PESSIMISTIC_READおよびPESSIMISTIC_WRITEを使用するコードでは、SQLが「for update」で呼び出されるのと同じ結果になります。
違いは、ロックメカニズムにあります。
PESSIMISTIC_READ
ロックは、そのようなロックがある場合、ダーティリードおよび繰り返し不可の読み取りが不可能であることを意味します。データを変更する必要がある場合は、PESSIMISTIC_WRITE
ロックを取得する必要があります
PESSIMISTIC_WRITE
ロックは、ダーティで繰り返し不可の読み取りに加えて、追加のロックを取得せずにデータを更新できることを保証します(排他ロックを待機している間はdeadlocks
を実行できます)。
╔══════════════════════╦══════════════════════════╦══════════════════════════╗
║ LockModeType ║ PESSIMISTIC_READ ║ PESSIMISTIC_WRITE ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ type ║ SHARED LOCK ║ EXCLUSIVE LOCK ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ isReadOnly without ║ ║ ║
║ additional locks ║ YES ║ NO ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ dirty reads ║ NO ║ NO ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ non-repeatable reads ║ NO ║ NO ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ how to update data ║ obtain PESSIMISTIC_WRITE ║ ALLOWED ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ ║ no one holds ║ no one holds ║
║ how to obtain lock ║ PESSIMISTIC_WRITE ║ PESSIMISTIC_READ or ║
║ ║ ║ PESSIMISTIC_WRITE ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ ║ ║ when there is a high ║
║ ║ you want to ensure no ║ likelihood of deadlock or║
║ when to use ║ dirty or non-repeatable ║ update failure among ║
║ ║ reads are possible ║ concurrent updating ║
║ ║ ║ transactions ║
╚══════════════════════╩══════════════════════════╩══════════════════════════╝
リソース:
1つは読み取りロック、もう1つは書き込みロック、または読み取り中または更新中です。
FTA:
PESSIMISTIC_READ。エンティティマネージャは、トランザクションがエンティティを読み取るとすぐにエンティティをロックします。ロックは、トランザクションが完了するまで保持されます。このロックモードは、反復可能読み取りセマンティクスを使用してデータをクエリする場合に使用されます。つまり、連続する読み取りの間にデータが更新されないようにする必要があります。このロックモードは、他のトランザクションによるデータの読み取りをブロックしません。
PESSIMISTIC_WRITE。エンティティマネージャは、トランザクションがエンティティを更新するとすぐにエンティティをロックします。このロックモードでは、エンティティデータの更新を試みるトランザクション間で強制的にシリアル化が行われます。このロックモードは、同時更新トランザクション間で更新が失敗する可能性が高い場合によく使用されます。
PESSIMISTIC_READ
は、関連するテーブル行レコードの共有(読み取り)ロックを取得しますが、PESSIMISTIC_WRITE
は、排他(書き込み)ロックを取得します。
共有ロックは、他の同時排他ロックリクエストをブロックしますが、他の共有ロックリクエストを続行できます。
排他ロックは、共有ロック要求と排他ロック要求の両方をブロックします。
言及する価値があるのは、Hibernateの場合、データベースが共有ロック(Oracleなど)をサポートしていない場合、共有ロックリクエスト(PESSIMISTIC_READ
)は、排他ロック要求(PESSIMISTIC_WRITE
)。
詳細については、 ロックに関するこの記事 と JPAの悲観的ロックタイプに関するこの記事 を参照してください。
仕様では、JPA実装でそれぞれに異なるタイプのデータベースロックを使用できます。ほとんどのデータベースには1種類の宣言ロックしかないため、ほとんどの実装では2つは同じです(違いはありません)。