2013-02-11 2 views
0

Je suis un peu confus sur les avantages du verrouillage optimiste en JPA.Le verrouillage optimiste empêche-t-il le blocage dans JPA?

J'ai effectué un test avec deux threads et une seule ligne sur une table d'entités versionnée.
Voici ce que j'ai trouvé:

Deuxième essai
T1: begin tran 
T1: fetch single entity 
T1: Update field in entity 
T1: sleep 
T2: begin tran 
T2: fetch single entity 
T2: Update field in entity 
T2: commit trans 
T1: wake up 
T1: commit trans - throws OptimisticLockException (expected) 

. Notez l'ajout d'une instruction select.

T1: begin tran 
T1: fetch single entity 
T1: Update field in entity 
T1: run select query on table (this causes a DB transaction to begin) 
T1: sleep 
T2: begin tran 
T2: fetch single entity (this blocks until DB transaction of thread T1 completes!) 
T2: Update field in entity 
T2: commit trans 
T1: wake up 
T1: commit trans - ok, no exception. The fetch/update/commit of T2 happened after T1 commit. 

Je ne me attendais pas tout blocage de se produire lors de l'utilisation verrouillage optimiste, mais je crois comprendre qu'une transaction de base de données doit être mis en place ici afin que les données correctes est renvoyée par l'instruction select.
Puisque JPA ne semble entrer dans les transactions de base de données que lorsque c'est absolument nécessaire, quelqu'un peut-il expliquer quels sont les avantages du verrouillage optimiste?

Répondre

1

Dans votre premier exemple, vous avez raison de dire que JPA reste accroché aux mises à jour jusqu'à ce qu'il ait absolument besoin de flush. Dans le second exemple, il doit les vider afin que le select travaille sur des données à jour.

Un avantage du verrouillage optimiste est que la base de données n'a pas besoin de verrouiller les tables. Cela permet à votre base de données de mieux évoluer car davantage de clients peuvent émettre des instructions à son encontre. L'inconvénient est qu'il déplace une grande partie de ce contrôle de concurrence dans la couche d'application. Cela signifie que vous devrez implémenter la gestion des erreurs ou réessayer la logique. Dans le cas où vous attendez pas de mises à jour contentieuses, cela peut être bon. Dans le cas où vous vous attendez à ce que de nombreux clients mettent à jour les mêmes entités JPA en même temps, il peut exiger une bonne quantité de logique d'application pour gérer les erreurs et réessayer intelligemment la mise à jour sans recourir à une situation de dernière écriture.

Vous trouverez peut-ce blog intéressant https://blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and

+0

Je suppose que ce qui me confond est que dans le second exemple ci-dessus, la ligne de base de données a été bloquée dès qu'une transaction de base de données a été conclu. Cela ne semblait pas aller mieux qu'un cas non optimiste. – Darren

+1

Je ne suis pas sûr que l'instruction "la ligne de base de données a été verrouillée dès qu'une transaction de base de données a été saisie" est vraie. Le verrouillage et les transactions sont des mécanismes distincts. – digitaljoel

+0

Oui. Je voulais dire que la transaction a été lancée et qu'une mise à jour de la ligne a été effectuée, ce qui entraîne le verrouillage de la ligne tout le temps que la transaction est ouverte. Il semble que même un verrouillage optimiste peut bloquer la ligne pendant une longue période si elle se produit dans une transaction de base de données? – Darren

Questions connexes