Locking controls concurrent access to data while a transaction is in progress. A database lock on an item can temporarily prevent other transactions from reading or writing it, helping provide transaction isolation. Lock behavior depends on the database; some engines instead use multi-version concurrency control (MVCC). section 11.2
In JPA, explicit pessimistic locking requests protection when data is loaded. PESSIMISTIC_READ guarantees repeatable reads. PESSIMISTIC_WRITE also requires serialized data access and prevents phantom reads. Hibernate commonly issues a locking SELECT, but the SQL varies by dialect: PostgreSQL uses FOR SHARE for reads and FOR UPDATE for writes, whereas H2 uses FOR UPDATE for both. section 11.2.3
Lock an entity before changing it
Begin a transaction, call EntityManager.find() with LockModeType.PESSIMISTIC_WRITE and a javax.persistence.lock.timeout hint, change the entity, then commit. If the locking query succeeds, the transaction can proceed knowing it has obtained the requested lock; if the lock cannot be obtained, an exception is thrown. The database lock lasts only for that transaction. section 11.2.3
Path: /Ch11/transactions/src/test/java/com/manning/javapersistence/ch11 /concurrency/Locking.java – findLock() EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); Map<String, Object> hints = new HashMap<>(); hints.put("javax.persistence.lock.timeout", 5000); Category category = #1 em.find( Category.class, CATEGORY_ID, LockModeType.PESSIMISTIC_WRITE, Hints ); category.setName("New Name"); em.getTransaction().commit(); em.close(); #1 Executes <kbd>SELECT ... FOR UPDATE WAIT 5000</kbd>, if supported by the dialect.
The listing places a pessimistic write lock on a Category during find(), before changing its name and committing. section 11.2.3
Lock timing matters. Hibernate normally delays UPDATE statements until the persistence context is flushed, often at commit; the resulting database locks are therefore held for as little of the transaction as possible. An explicit pessimistic lock is acquired earlier. Optimistic concurrency control makes a different tradeoff: a conflict may surface at commit rather than when the entity is queried. section 10.2.3 section 11.2.3
Locks can also cause deadlocks. If two transactions update the same rows in opposite orders, each may wait for a lock held by the other; the database typically aborts one transaction. Acquiring exclusive locks when selecting the data is one option. Ordering UPDATE statements consistently by primary key, using Hibernate’s hibernate.order_updates setting, reduces the probability of this pattern. Keep transactions short: open transactions consume resources and may block concurrent access. section 11.2.4 section 11.1.2

















