为了账号安全,请及时绑定邮箱和手机立即绑定

spring jpa crud 存储库在多线程环境中从数据库中获取旧数据

spring jpa crud 存储库在多线程环境中从数据库中获取旧数据

慕的地8271018 2023-03-17 14:07:01
我正在使用 mysql 数据库和 kafka 作为消息服务运行 spring boot 应用程序(使用 chainedKafkaTransactionManager 为 kafka 和 mysql 进行事务同步)以进行一些异步操作。当多条消息到达 kafka 监听器时,旧数据来自数据库而不是以前提交的数据。我正在使用 crud 存储库,而且这种情况只会同时发生在多条消息上示例:更新一个具有名称和 ID 的对象 PERSON;第一条消息将通过 id 获取对象并将名称更新为 SAM。第二条消息将获取对象并将名称更新为 REGO第三条消息将获取对象,然后如果我检查它包含 SAM 作为名称的数据,但在数据库中它有 REGO。我尝试添加隔离属性作为事务中提交的读取但没有运气// listeners  @Autowiredprivate PersonRepository personRepository;@Autowiredprivate AddressRepository addressRepository;     @KafkaListener(id = "update_name", topics = "update_name")@Transactional(readOnly = false)public void updateName(PersonModel personModel) {    Person person = personRepository.findById(personModel.getId());       log.info("before -> name which is in database : " + person.getName());    person.setName(personModel.getName());    person = personRepository.save(person);    log.info("after-> name which is in database : " + person.getName());}@KafkaListener(id = "update_name_and_address", topics = "update_name_and_address")@Transactional(readOnly = false)public void updateNameAndAddress(PersonModel personModel) {    Address addr= addressRepository.findById(personModel.getAddresId);        addr.setPlace(personModel.getPlace());    addressRepository.save(addr);    updateName(personModel);}// repositorypublic interface PersonRepository extends CrudRepository<Person , Integer> {}我需要数据库中的最新数据
查看完整描述

1 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

当第三个事务在第二个事务提交之前开始时,就会发生这种情况。效果变得更加明显,因为一旦在会话中加载实体,JPA 就不会重新加载它。

为了尽量减少这个问题,请尽可能缩短您的交易时间。还要确保您可能通过在新事务中重试来处理乐观锁定异常。


查看完整回答
反对 回复 2023-03-17
  • 1 回答
  • 0 关注
  • 140 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号