JPA 悲观锁不起作用

Orb*_*rby 6 oracle hibernate jpa locking transactions

我使用 Spring Boot、JPA、Oracle 12C 和下面的类型化查询来选择要处理的“新”项目。选择“新”项目后,我会更新其状态,使其不再符合选择条件,但我发现选取相同项目时存在并发问题。

在这里读到,我需要在查询上设置“LockModeType.PESSIMISTIC_WRITE”,以防止其他线程选择同一行,但它似乎不起作用。

我是否错过了下面的内容,或者我是否需要其他配置来防止并发线程从我的表中检索相同的行?问题是否与锁定级别或实体管理器未更新/刷新有关?

我的@Transactional服务:

@Override
@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor=RuntimeException.class)
public MyObject retrieveItemByStatus(StatusEnum status) {
    return myRepository.retrieveItemByStatus(status);
}
Run Code Online (Sandbox Code Playgroud)

我的存储库层中的查询:

@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;
}
Run Code Online (Sandbox Code Playgroud)

osa*_*oub 1

AFAIK你不能在oracle中阻止“读取”...悲观锁对应的select for update不会阻止其他select语句...它只强制它读取旧版本的数据(在运行之前select for update)...它将阻止仅其他select for update语句(因此其他查询具有悲观锁)