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

Java interview question for Advanced practice.

Answer

Pessimistic and optimistic locking are two strategies for managing concurrent database transactions. Pessimistic Locking: Mechanism: This strategy assumes that conflicts are likely. It locks the database row (or rows) when data is read, preventing any other transaction from reading or modifying that data until the lock is released (usually at the end of the transaction). In Spring Data JPA, this is typically done using @Lock(LockModeType.PESSIMISTICWRITE). Pros: Guarantees that the data will not be changed by another transaction, preventing conflicts entirely. Cons: Can severely reduce concurrency and throughput, as other transactions must wait. It can also lead to deadlocks if not managed carefully. Use Case: Best for systems with high contention for the same data, where data consistency is absolutely critical and transaction times are short (e.g., a financial system transferring funds). Optimistic Locking: Mechanism: This strategy assumes conflicts are rare. It does not lock the data when read. Instead, it uses a version column (annotated with @Version) on the entity. When a transaction tries to update a row, it checks if the version number in the database is the same as the version number it originally read. If it is, the update proceeds and the version number is incremented. If not, it means another transaction has modified the data, and an OptimisticLockException is thrown. Pros: High concurrency and throughput, as it doesn't hold database locks. Cons: Does not prevent conflicts, only detects them. The application must be prepared to handle the exception (e.g., by retrying the transaction or informing the user). Use Case: Best for most web applications where contention is low (users are typically modifying different data) and high throughput is important.

Explanation

Spring Data JPA provides the @Lock annotation to declaratively apply pessimistic locks to repository query methods.

Related Questions