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:
2026-10-25 17:01:49 +00:00
co-authored by Claude Sonnet 5.5
parent 807f681ed1
commit 357ba84e5c
18 changed files with 758 additions and 0 deletions
+7
View File
@@ -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=?
+9
View File
@@ -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=?
+5
View File
@@ -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)
+8
View File
@@ -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
+8
View File
@@ -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
+7
View File
@@ -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
+10
View File
@@ -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