使用多个线程

时间:2017-10-30 13:50:18

标签: java multithreading oracle hibernate locking

我无法让SELECT FOR UPDATE在Hibernate和Oracle中工作。

当我有两个线程,每个线程有一个EntityManager时,第二个线程似乎能够读取与第一个相同的行。我可以通过添加跟踪来看到这一点,这些跟踪显示第二个线程读取同一行,而第一个线程在query.getSingleResult()entityManager.getTransaction().commit()之间。我的期望是,一旦发出SELECT FOR UPDATE,其他任何人都不应该能够读取同一行,直到它被第一个线程提交。但这种情况并没有发生。

我可以使用替代实现。我想要实现的只是一个进程能够读取和更新Oracle表中的一行,以便它的行为就像一个队列,因为消费者进程可以在不同的机器上。

以下是我的代码的最小示例:

public MyMessage getNextMessage() {
    String sql = "SELECT * FROM MESSAGE WHERE MESSAGE_STATUS = 'Pending' AND rownum=1 FOR UPDATE OF MESSAGE_STATUS";
    entityManager.getTransaction().begin();
    Query query = entityManager.createNativeQuery(sql, MyMessage.class);
    query.setLockMode(LockModeType.PESSIMISTIC_WRITE);
    MyMessage msg = null;
    try {
        msg = (MyMessage) query.getSingleResult();
    } catch (NoResultException nodatafound) {
        // Ignore when no data found, just return null
    }
    if (msg != null) {
        msg.setMessageStatus("In Progress");
        entityManager.persist(msg);
    }
    entityManager.getTransaction().commit();
    return msg;
}

0 个答案:

没有答案