Я впервые реализую LockModeType.PESSIMISTIC_WRITE в JPA, и я не могу быть уверен в последовательности.
Например, у меня есть два метода в моем общем DAO:
public T getByIdWithLock(Integer id, Class<T> clazz) {
em = new JPAUtil().getEntityManager();
T t;
try {
em.getTransaction().begin();
em.setProperty("javax.persistence.lock.timeout", 0);
t = em.find(clazz, id, LockModeType.PESSIMISTIC_WRITE);
return t;
} catch (PessimisticLockException | LockTimeoutException e) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Atenção!", "O registro está sendo alterado por outro usuário.");
FacesContext.getCurrentInstance().addMessage(null, message);
LOGGER.log(Level.SEVERE, e.toString(), e);
em.getTransaction().rollback();
em.close();
return null;
}
}
public boolean updateWithLock(T t) {
try {
//lock commit before update
em.getTransaction().commit();
em.getTransaction().begin();
em.merge(t);
em.getTransaction().commit();
return true;
} catch (Exception e) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro!", "Não foi possivel alterar " + t.getClass().getSimpleName());
FacesContext.getCurrentInstance().addMessage(null, message);
LOGGER.log(Level.SEVERE, e.toString(), e);
em.getTransaction().rollback();
return false;
} finally {
em.close();
}
}
Обычно, в примере, мой пользователь получает запись из базы данных, редактирует и выполняет обновление. В фоновом режиме getByIdWithLock получает запись и блокирует ее, затем в updateWithLock снимает блокировку с
em.getTransaction().commit();
и сделайте обновление с обычным
em.merge(t);
Я не видел никаких проблем до сих пор, но я точно не знаю, может ли другой пользователь между блокировкой commit () и merge () снова заблокировать запись, создавая беспорядок в процессе. И если они могут, как я могу предотвратить?