我正在使用Spring Boot、JPA、Oracle 12C和下面的Typed Query来选择“NEW”项目进行处理。一旦我选择了一个“NEW”项目,我会更新它的状态,使其不再有资格被选择,但我发现同样的项目出现了并发问题。
我在这里读到,我需要在查询上设置“LockModeType.PESSIMISTIC_WRITE”以防止其他线程选择相同的行,但似乎没有起作用。
我是否漏掉了下面的内容或者需要另一种配置来防止并发线程从我的表中检索相同的行?问题与锁级别还是实体管理器未得到更新/刷新有关?
我的
我在这里读到,我需要在查询上设置“LockModeType.PESSIMISTIC_WRITE”以防止其他线程选择相同的行,但似乎没有起作用。
我是否漏掉了下面的内容或者需要另一种配置来防止并发线程从我的表中检索相同的行?问题与锁级别还是实体管理器未得到更新/刷新有关?
我的
@Transactional
服务:@Override
@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor=RuntimeException.class)
public MyObject retrieveItemByStatus(StatusEnum status) {
return myRepository.retrieveItemByStatus(status);
}
我的仓库层中的查询:
@Override
public MyObject retrieveItemByStatus(StatusEnum status) {
String sql = "SELECT t FROM myTable t WHERE status = :status ORDER BY id ASC";
try {
TypedQuery<MyObject> query = em.createQuery(sql, MyObject.class).setParameter("status", status);
query.setLockMode(LockModeType.PESSIMISTIC_WRITE);
query.setFirstResult(0);
query.setMaxResults(1);
MyObject myObject = (MyObject) query.getSingleResult();
if (myObject != null) {
myObject.setStatus(StatusEnum.IN_PROGRESS);
MyObject myUpdatedObject = em.merge(myObject);
return myUpdatedObject;
}
} catch (IllegalArgumentException iae) {
//some logging
} catch(NoResultException nrf) {
//some logging
} catch(Exception ex) {
//some logging
}
return null;
}