In Hibernate, locking is the mechanism that is used to prevent concurrent access to data by multiple threads or processes. It ensures that only one thread or process can modify a particular set of data at a time, thus maintaining data consistency and integrity. Hibernate supports two types of locking: optimistic locking and pessimistic locking.
Optimistic locking is a concurrency control mechanism that assumes that conflicts between transactions are rare. In optimistic locking, a version number or a timestamp is associated with each entity. When an entity is updated, the version number or timestamp is incremented. When a transaction tries to update an entity, Hibernate checks the version number or timestamp of the entity against the version number or timestamp in the database. If they match, the transaction can proceed with the update. If they do not match, it means that the entity has been updated by another transaction in the meantime, and the current transaction must be rolled back.
Here is an example of how to use optimistic locking in Hibernate:
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String author;
@Version
private int version;
// getters and setters
}
@Repository
public class BookRepository {
@Autowired
private EntityManager entityManager;
@Transactional
public void updateBookTitle(Long id, String newTitle) {
Book book = entityManager.find(Book.class, id);
book.setTitle(newTitle);
entityManager.merge(book);
}
}
In the above example, the Book entity has a version field annotated with @Version. When the entity is updated, Hibernate automatically increments the version field. In the BookRepository class, the updateBookTitle method updates the title of a book identified by its ID. When the entityManager.merge(book) method is called, Hibernate checks the version of the book against the version in the database. If they match, the update is applied, and the version is incremented. If they do not match, a javax.persistence.OptimisticLockException is thrown.
Pessimistic locking, on the other hand, is a concurrency control mechanism that assumes that conflicts between transactions are common. In pessimistic locking, a lock is acquired on the data before updating it, and the lock is released after the update is complete. Pessimistic locking can be implemented in Hibernate using the LockModeType enumeration. Hibernate provides four lock modes:
LockModeType.READ: Acquires a shared lock, which allows other transactions to read the data but not modify it.
LockModeType.WRITE: Acquires an exclusive lock, which prevents other transactions from reading or modifying the data.
LockModeType.OPTIMISTIC: Acquires an optimistic lock, which allows other transactions to read the data but not modify it until the lock is released.
LockModeType.PESSIMISTIC_READ: Acquires a pessimistic shared lock.
LockModeType.PESSIMISTIC_WRITE: Acquires a pessimistic exclusive lock.
Here is an example of how to use pessimistic locking in Hibernate:
@Repository
public class BookRepository {
@Autowired
private EntityManager entityManager;
@Transactional
public void updateBookTitle(Long id, String newTitle) {
Book book = entityManager.find(Book.class, id, LockModeType.PESSIMISTIC\_WRITE);
book.setTitle(newTitle);
entityManager.merge(book);
}
}
In the above example, the entityManager.find method is called with the LockModeType.PESSIMISTIC_WRITE argument, which acquires an exclusive lock on the book entity. This prevents other transactions from reading or modifying the entity until the lock is released.