Add locking module: optimistic vs pessimistic locking on Hibernate 7.4.14.Final
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YPgGH6aMbSLANL3E2HHmS6
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
start balance 100; transaction A deposits 10, transaction B deposits 20
|
||||
both read 100 before either writes; A commits first, then B
|
||||
final balance: 120 (a correct result would be 130)
|
||||
|
||||
update statements Hibernate sent:
|
||||
update Account set balance=?,owner=? where id=?
|
||||
update Account set balance=?,owner=? where id=?
|
||||
@@ -0,0 +1,9 @@
|
||||
same race, entity has @Version
|
||||
A: committed. B: failed
|
||||
B exception: jakarta.persistence.OptimisticLockException
|
||||
caused by: org.hibernate.StaleObjectStateException
|
||||
final balance: 110, version: 1
|
||||
|
||||
update statements Hibernate sent:
|
||||
update VersionedAccount set balance=?,owner=?,version=? where id=? and version=?
|
||||
update VersionedAccount set balance=?,owner=?,version=? where id=? and version=?
|
||||
@@ -0,0 +1,5 @@
|
||||
6 threads x 5 deposits of 1, each retried on OptimisticLockException
|
||||
final balance: 30 (expected 30)
|
||||
version: 30
|
||||
retries happened: true
|
||||
retry count in this run: 27 (varies from run to run)
|
||||
@@ -0,0 +1,8 @@
|
||||
A locks row 1 with PESSIMISTIC_WRITE, holds it 600 ms, deposits 10
|
||||
B asks for the same lock, then deposits 20
|
||||
B waited at least 400 ms for the lock: true
|
||||
final balance: 130 (correct: 130)
|
||||
|
||||
select statements Hibernate sent (one per transaction):
|
||||
select a1_0.id,a1_0.balance,a1_0.owner from Account a1_0 where a1_0.id=? for update
|
||||
select a1_0.id,a1_0.balance,a1_0.owner from Account a1_0 where a1_0.id=? for update
|
||||
@@ -0,0 +1,8 @@
|
||||
A holds the lock; B asks with Timeouts.NO_WAIT
|
||||
B exception: org.hibernate.exception.LockTimeoutException
|
||||
caused by org.h2.jdbc.JdbcSQLTimeoutException
|
||||
H2 message: Timeout trying to lock table "ACCOUNT"; SQL statement:
|
||||
caused by org.h2.mvstore.MVStoreException
|
||||
|
||||
select statements B sent:
|
||||
select a1_0.id,a1_0.balance,a1_0.owner from Account a1_0 where a1_0.id=? for update nowait
|
||||
@@ -0,0 +1,7 @@
|
||||
5 tickets, all NEW. Worker A claims 2 and keeps its transaction open.
|
||||
Worker B claims 2 with SKIP LOCKED.
|
||||
A got tickets: [1, 2]
|
||||
B got tickets: [3, 4]
|
||||
|
||||
select statements B sent:
|
||||
select t1_0.id,t1_0.claimedBy,t1_0.status from Ticket t1_0 where t1_0.status='NEW' order by t1_0.id fetch first ? rows only for update skip locked
|
||||
@@ -0,0 +1,10 @@
|
||||
opposite lock order (A: 1 then 2, B: 2 then 1)
|
||||
transactions that failed: 1
|
||||
jakarta.persistence.PessimisticLockException
|
||||
caused by org.hibernate.exception.LockAcquisitionException
|
||||
caused by org.h2.jdbc.JdbcSQLTransactionRollbackException
|
||||
H2 message: Deadlock detected. The current transaction was rolled back. Details: "ACCOUNT"; SQL statement:
|
||||
caused by org.h2.mvstore.MVStoreException
|
||||
|
||||
same lock order for both (always the lower id first)
|
||||
transactions that failed: 0
|
||||
Reference in New Issue
Block a user