# locking Companion module for the ankurm.com article on **optimistic vs pessimistic locking in Hibernate 7**. Two threads, one in-memory H2 database, plain Hibernate (no Spring). Each test writes what it observed to `output/`. ## Versions | Component | Version | Notes | |---|---|---| | Hibernate ORM | `7.4.14.Final` | latest 7.x GA on Maven Central on 2026-10-25 (`8.0.0.Beta3` is also listed; it is not GA) | | Jakarta Persistence | `3.2.0` | | | H2 | `2.4.240` | in memory, `OPTIMIZE_REUSE_RESULTS=0` (see `Db.java`) | | JUnit Jupiter / AssertJ | `6.0.3` / `3.27.7` | | | Java | `25` (Temurin 25.0.5+8) | | This module has its own `pom.xml` and does not use the Spring Boot parent of the main `hibernate-demo` project. All locking behaviour here is H2's. `SKIP LOCKED`, `NOWAIT` and deadlock handling differ between databases, so check your own. ## Run ```bash ./scripts/run-all.sh ``` ## Output | File | What it shows | |---|---| | `01-lost-update.txt` | two transactions read 100, both deposit, one deposit is lost (no `@Version`) | | `02-version-stops-it.txt` | the same race with `@Version`: the second commit fails with `OptimisticLockException` | | `03-retry-loop.txt` | six threads, thirty increments, retry on `OptimisticLockException`; the final balance is exact | | `04-pessimistic-write.txt` | `PESSIMISTIC_WRITE` makes the second transaction wait; SQL uses `for update` | | `05-no-wait.txt` | `Timeouts.NO_WAIT` fails at once (`for update nowait`) | | `06-skip-locked.txt` | two workers claim different tickets (`for update skip locked`) | | `07-deadlock.txt` | opposite lock order deadlocks; the same order for everyone does not |