J'ai lu l'article Verrouillage et accès simultané dans Java Persistence 2. , et j'ai exécuté l'exemple d'application. Mais je n'arrive toujours pas à comprendre la différence entre PESSIMISTIC_READ et PESSIMISTIC_WRITE. J'ai essayé de modifier le code, et où le code utilisant PESSIMISTIC_READ et PESSIMISTIC_WRITE aura le même résultat que le sql sera invoqué avec "for update".
La différence réside dans le mécanisme de verrouillage.
PESSIMISTIC_READ
lock signifie que les lectures incorrectes et les lectures non répétables sont impossibles lorsque vous disposez d'un tel verrou. Si les données doivent être modifiées, il est nécessaire d'obtenir PESSIMISTIC_WRITE
fermer à clé
PESSIMISTIC_WRITE
lock garantit qu'en plus des lectures sales et non répétables, il est impossible de mettre à jour les données sans obtenir de verrous supplémentaires (et éventuellement deadlocks
en attendant le verrouillage exclusif).
╔══════════════════════╦══════════════════════════╦══════════════════════════╗
║ 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 ║
╚══════════════════════╩══════════════════════════╩══════════════════════════╝
Ressources:
L'un est un verrou en lecture et l'autre est un verrou en écriture, ou lors d'une lecture ou d'une mise à jour, respectivement.
ALE:
PESSIMISTIC_READ. Le gestionnaire d'entité verrouille l'entité dès qu'une transaction la lit. Le verrou est maintenu jusqu'à la fin de la transaction. Ce mode de verrouillage est utilisé lorsque vous souhaitez interroger des données à l'aide d'une sémantique à lecture répétable. En d'autres termes, vous voulez vous assurer que les données ne sont pas mises à jour entre les lectures successives. Ce mode de verrouillage n'empêche pas les autres transactions de lire les données.
PESSIMISTIC_WRITE. Le gestionnaire d'entités verrouille l'entité dès qu'une transaction la met à jour. Ce mode de verrouillage force la sérialisation des transactions qui tentent de mettre à jour les données d'entité. Ce mode de verrouillage est souvent utilisé lorsqu'il existe une forte probabilité d'échec de la mise à jour parmi les transactions de mise à jour simultanées.
Le PESSIMISTIC_READ
acquiert un verrou partagé (lecture) sur l'enregistrement de ligne de table associé, tandis que PESSIMISTIC_WRITE
acquiert un verrou exclusif (écriture).
Le verrou partagé bloque toute autre demande de verrouillage exclusif simultanée, mais il permet à d'autres demandes de verrouillage partagé de continuer.
Le verrou exclusif bloque les demandes de verrouillage partagées et exclusives.
Il convient de mentionner que, pour Hibernate, si la base de données ne prend pas en charge les verrous partagés (par exemple Oracle), une demande de verrouillage partagé (PESSIMISTIC_READ
) acquiert simplement une demande de verrouillage exclusif (PESSIMISTIC_WRITE
).
Pour plus de détails, consultez cet article sur les verrous et cet article sur les types de verrous pessimistes JPA .
La spécification permet à l'implémentation JPA d'utiliser un type de verrouillage de base de données différent pour chacun. La plupart des bases de données n'ont qu'un seul type de verrou déclaratif, donc dans la plupart des implémentations, les deux sont identiques (il n'y a pas de différence).