Compare and contrast optimistic and pessimistic locking in the context of Spring Data JPA. When would you choose one over the other?

Java interview question for Advanced practice.

Answer

Optimistic and pessimistic locking are two strategies for handling concurrent database updates to prevent issues like the 'lost update' problem. Optimistic Locking: Mechanism: Assumes that conflicts are rare. It does not lock the data when it's read. Instead, it uses a version column (typically a number or timestamp annotated with @Version in the entity) to detect if the data has been modified by another transaction. When the application tries to commit its update, the JPA provider checks if the version in the database matches the version it originally read. If not, it throws an OptimisticLockException, and the transaction is rolled back. When to use: It's the preferred choice for most web applications and high-concurrency scenarios. It has much better performance and scalability because it doesn't hold database locks, minimizing contention. Drawback: The application must be prepared to handle the OptimisticLockException, usually by informing the user that the data has changed and they need to retry their operation. Pessimistic Locking: Mechanism: Assumes that conflicts are likely. It acquires a lock on the data at the database level as soon as it is read (e.g., using a SELECT ... FOR UPDATE query). This lock prevents any other transaction from modifying or sometimes even reading the data until the current transaction completes. When to use: It is suitable for low-concurrency environments or situations where conflicts are very frequent and the cost of retrying a failed optimistic transaction is high. It can also be useful when business logic requires that data absolutely cannot change after being read. Drawback: It significantly reduces concurrency. If a transaction holds a lock for a long time, it can block other users and become a major performance bottleneck. It also increases the risk of deadlocks.

Explanation

Spring Data JPA allows you to request a pessimistic lock by using the @Lock annotation on a repository query method, for example @Lock(LockModeType.PESSIMISTICWRITE).

Related Questions