How to ensure correct updating of the same entity during concurrent transactions of competing threads?
sobes.tech AI
Answer from AI
To correctly update the same entity during concurrent transactions in Java, mechanisms for managing concurrent access are usually used, such as:
-
Optimistic Locking — assumes conflicts are rare and checks the entity's version before committing. If the version has changed, the transaction is rolled back and retried. In JPA, this is implemented using the
@Versionannotation. -
Pessimistic Locking — locks the record for the duration of the transaction, preventing other transactions from reading or modifying the entity. In JPA, methods like
EntityManager.lock()with the lock typePESSIMISTIC_WRITEcan be used. -
Application-level Synchronization — using
synchronizedor other thread locking mechanisms to ensure sequential access.
Example of optimistic locking with JPA:
@Entity
public class Product {
@Id
private Long id;
@Version
private Integer version;
private int quantity;
// getters and setters
}
// In the service
@Transactional
public void updateQuantity(Long productId, int delta) {
Product product = entityManager.find(Product.class, productId);
product.setQuantity(product.getQuantity() + delta);
// When committing, JPA will check the version and throw an OptimisticLockException if it was changed
}
Thus, during concurrent updates, one of the transactions will be rejected, and it can be retried.