Skip to content

umur/jpa-locking

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

jpa-locking

Companion repo for the tutorial: Optimistic vs Pessimistic Locking in JPA

Demonstrates the lost update problem and both JPA solutions using a Product inventory example with real PostgreSQL via Testcontainers.

Run the tests

mvn verify

Docker must be running. Testcontainers starts a PostgreSQL 16 container automatically.

What each test proves

OptimisticLockingIT

  • versionFieldIncrementsOnEachUpdate - the @Version column starts at 0 and increments on every UPDATE
  • updateIncludesVersionCheck - Hibernate appends WHERE version = ? to every UPDATE statement
  • concurrentModificationThrowsOptimisticLockException - a stale write is rejected with ObjectOptimisticLockingFailureException instead of silently overwriting the earlier change

PessimisticLockingIT

  • findByIdWithLockIssuesSelectForUpdate - @Lock(PESSIMISTIC_WRITE) generates SELECT ... FOR UPDATE
  • concurrentAccessProducesCorrectStock - two threads each reduce stock by 3 from a starting value of 10; the result is always exactly 4 with no errors

Project structure

src/main/java/com/umurinan/jpalocking/
├── entity/
│   └── Product.java                   # @Version field enables optimistic locking
├── repository/
│   └── ProductRepository.java         # findByIdWithLock uses @Lock(PESSIMISTIC_WRITE)
├── service/
│   ├── OptimisticInventoryService.java # relies on @Version, retries on conflict
│   └── PessimisticInventoryService.java # uses SELECT FOR UPDATE
└── JpaLockingApplication.java

Stack

  • Spring Boot 4.0.5
  • Java 21
  • Spring Data JPA / Hibernate
  • PostgreSQL 16 (via Testcontainers)

About

Optimistic vs pessimistic locking in JPA - preventing the lost update problem

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages