【问题标题】:OptimisticLockException in pessimistic locking悲观锁定中的 OptimisticLockException
【发布时间】:2014-12-08 11:16:54
【问题描述】:

我正在使用 Spring 和 Hibernate。我正在像这样运行 jUnit 测试:

String number = invoiceNumberService.nextInvoiceNumber();

invoiceNumberService 方法是:

InvoiceNumber invoiceNumber = invoiceNumberRepository.findOne(1L);

它使用简单的spring数据存储库方法,并且运行良好。但是当我重写此方法以使用锁定时:

@Lock(LockModeType.PESSIMISTIC_READ)
@Override
InvoiceNumber findOne(Long id);

我收到“javax.persistence.OptimisticLockException:行已被另一个事务更新或删除”

我不明白为什么它的乐观锁异常,而我正在使用悲观锁?当另一个交易改变这个实体时,这部分在哪里? 我已经挖掘了很多类似的问题,对此我感到非常绝望。谢谢你的帮助

解决方案:
问题出在我在测试类中的初始化函数中:

@Before
public void init() {
    InvoiceNumber invoiceNumber = new InvoiceNumber(1);
    em.persist(invoiceNumber);
    em.flush();
}

缺少了

em.flush();

这会将数据保存到数据库中,因此 findOne() 现在可以检索它

【问题讨论】:

  • 我遇到了同样的问题和同样的解决方案。对我来说,Hibernate 不会自行刷新,这听起来像是一个错误。

标签: java spring hibernate jakarta-ee


【解决方案1】:

问题:你在dao或者service层给@transcational注解了吗? 发生这种情况是因为两个事务同时尝试更改同一张表的数据。所以如果你从 dao 层删除所有注释并放入服务层,它应该可以解决这个问题。因为我面临类似的问题。 希望能帮助到你。

【讨论】:

  • 你有没有从上到下阅读问题? OP 错误地将答案发布在问题本身而不是答案中。
【解决方案2】:

只是为了它,我会发布以下内容,如果有人不同意,请纠正我。一般来说,在 java 中,建议您使用 Spring/hibernate 和 JPA。 Hibernate 实现了 JPA,因此您将需要 Spring 和 Hibernate 的依赖项。

接下来让 Spring/hibernate 管理您的事务和提交部分。自己刷新/提交数据是不好的做法。

例如假设以下方法:

public void changeName(long id, String newName) {
   CustomEntity entity = dao.find(id);
   entity.setName(newName);
}

在这个方法之后什么都不会发生(你可以调用合并和提交)。但是如果你用@Transactional 注释它,你的实体将被管理,并且在@Transactional 方法结束时Spring/hibernate 将提交你的更改。所以这就够了:

@Transactional
public void changeName(long id, String newName) {
   CustomEntity entity = dao.find(id);
   entity.setName(newName);
}

无需调用 flush,Spring/Hibernate 将为您处理所有的混乱。只是不要忘记您的测试必须调用@Transactional 方法,或者本身应该是@Transactional。

【讨论】:

    猜你喜欢
    • 2010-09-12
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    相关资源
    最近更新 更多