当前位置: 首页 > 知识库问答 >
问题:

Spring Boot下并发JPA更新的OptimisticLockException

百里京
2023-03-14

这里是再现异常的示例项目。

    null
@Override
public Account getLockedAccount(Integer id) {
    final Account account = findOne(id);
    em.lock(account, LockModeType.PESSIMISTIC_WRITE);
    return account;
}
{  
"timestamp":1425407408204,
"status":500,
"error":"Internal Server Error",
"exception":"org.springframework.orm.ObjectOptimisticLockingFailureException",
"message":"Object of class [sample.data.jpa.domain.Account] with identifier [1]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [sample.data.jpa.domain.Account#1]",
"path":"/tx/1443/stop/46.4"
}

UPD:使用任务执行器的工作放在另一个分支中。SpringThreadPoolTaskExecutor与事务性任务相结合可以解决这个问题。

共有1个答案

虞滨海
2023-03-14

在查找和锁定之间,帐户对象可能已经被修改。你需要在一个语句中完成它

em.find(account.class,id,lockmodetype.pessimistic_write)

 类似资料:
  • 我已经尝试使用Spring Boot+Spring Data JPA更新实体很久了。我得到所有正确的观点回到我。我的编辑视图按ID向我返回正确的实体。一切进展顺利。直到我实际尝试保存/合并/持久化对象。每次我拿回一个有新ID的新实体。我只是不知道为什么。我看了网上的例子,还有你可能会参考的重复问题的链接。那么,在这些代码中,我在哪里犯了错误呢? 在这段代码之后。我的视图将我返回到正确的URL,但I

  • 问题内容: 我有一个表,与领域,和日期时间在一个MySQL的InnoDB数据库。 每次流程获得一项工作时,它都会“签出”该工作以将其标记为已开始,以便其他任何流程都无法对其进行处理。 我希望一个会话的单个过程能够: 寻找排名最高的工作 将此作业的开始字段更新为当前时间戳 而不会冒任何其他会话也可以选择并开始排名最高的工作的风险。其他会议也随时改变排名。 这是我的尝试: 但这失败了: 无论如何,我宁

  • 问题内容: 当前,我们在数据层中使用JDBC,并计划用hibernate代替它。我是Hibernate的新手,不确定Hibernate如何处理并发。如果我们使用spring进行事务管理,有人可以解释一下我如何处理并发更新:通过hibernate(在内存中进行hibernate的自动版本管理),或者我必须将version列放入数据库中以手动处理并发更新。 问题答案: 无论你是否使用Spring进行事

  • 本文向大家介绍springboot高并发下提高吞吐量的实现,包括了springboot高并发下提高吞吐量的实现的使用技巧和注意事项,需要的朋友参考一下 公司让做一个全文检索的项目,我使用的是elasticsearch。但是对性能有很高的要求,为了解决性能问题,我简直是寝食难安。 es(elasticsearch)没有使用分布式,单台的。 开发完测试的时候,查询慢,吞吐量低。 网友们建议用异步--使

  • (使用Spring Boot 2.3.3和MySQL 8.0。) 假设我有一个实体,其中包含一个字段,其中一个帐户实体代表某种主帐户。即该主帐户的字段几乎每笔交易都会更新,对该字段的任何更新都必须针对最近的值进行。 在这样的交易中,哪一个是更好的选择: > < li> 使用< code >悲观_写入锁,获取主帐户,增加总计字段,并提交事务。或者, 有一个专门的查询,本质上是这样做的,作为事务的一部

  • 问题内容: 我在玩JPA(具体来说是Eclipselink)。下面的实体具有一个时间戳,应该在该实体上次更新时反映该时间戳。 每次更改此实体时,使JPA自动更新该时间戳的策略是什么? 如果我还想要一个“创建”时间戳记,该时间戳记仅在实体首次保留时设置,而永远不允许再次更改,该怎么办? 问题答案: 使用@PrePersist和@PreUpdate批注并编写您自己的事件侦听器。 详细了解一下此答案。它