java - spring jpa crud 存储库在多线程环境中从数据库中获取旧数据
问题描述
我正在使用 mysql 数据库和 kafka 作为消息传递服务运行 spring boot 应用程序(使用 chainedKafkaTransactionManager 为 kafka 和 mysql 进行事务同步)以进行一些异步操作。
当多条消息到达kafka监听器时,有时来自数据库的旧数据而不是先前提交的数据。
我正在使用 crud 存储库,而且这种情况仅同时发生在多条消息上
示例:更新具有名称和 ID 的一个对象 PERSON;
第一条消息将通过 id 获取对象并将名称更新为 SAM。
第二条消息将获取对象并将名称更新为 REGO
第三条消息将获取该对象,然后如果我检查它包含 SAM 作为名称但在数据库中它具有 REGO 的数据。
我尝试在事务中添加隔离属性作为读取提交但没有运气
// listeners
@Autowired
private PersonRepository personRepository;
@Autowired
private 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);
}
// repository
public interface PersonRepository extends CrudRepository<Person , Integer> {
}
我需要数据库中的最新数据
解决方案
当第三个事务在第二个事务提交之前开始时,就会发生这种情况。效果变得更加明显,因为 JPA 在会话中加载实体后不会重新加载它。
为了尽量减少这个问题,让您的交易尽可能短。还要确保您可能通过在新事务中重试来处理乐观锁定异常。
推荐阅读
- http-status-code-404 - 如何在 Laravel 5.7 中创建自定义 404 页面?
- angular - Angular 没有向后端发送 PUT 请求
- vue.js - 如何在 Vue 中重用具有嵌套嵌套路由的命名视图?
- ios - 检查布尔值是否为真 x 秒 - Swift
- wordpress - 如何从 Photoswipe WooCommerce 图片库中隐藏图片标题?
- c# - 在 C# 中将数据从一个表单文本框移动到另一个表单文本框
- html - 如何使用垂直字体创建垂直菜单?
- php - Laravel 5.8 找不到路由页面 404 错误
- django - 单击href Django时如何不附加/ home /
- python - 如何从动态网站python selenium中检索表