【发布时间】:2023-01-20 04:14:43
【问题描述】:
我有一个带有 PostgreSQL 数据库的 Java、Spring Data 应用程序,并且在我的服务层中有一个与此类似的代码:
public void method1() {
PersonDto dto = method2();
method3(dto);
}
@Transactional
public PersonDto method2() {
Person p1 = personRepository.saveAndFlush(new Person());
return createPersonDto(p1);
}
@Transactional
public void method3(PersonDto p1) {
Person p2 = personRepository.findById(p1.getId());
if (p2 == null) {
System.out.println("Not in the DB");
} else {
System.out.println("In the DB");
}
}
有时这段代码打印“不在数据库中”,而我期望它总是打印“在数据库中”。我的问题是:
- 这个 saveAndFlush 有必要吗?由于我没有在同一笔交易中重复使用该实体,我猜它与保存具有相同的效果,对吗?
- 如何保证方法2的修改在方法3调用之前提交?所以它总是打印“在数据库中”?
- 我正在将我的实体转换为 DTO 的事实是什么搞砸了?也许如果我传递实体本身它会正常工作?
我正在考虑仅在 method1 中使用 @Transactional,或者将 method3 中的 @Transactional 替换为 @Transactional(isolation = Isolation.READ_UNCOMMITTED)。 有什么建议吗?
【问题讨论】:
-
1. 您确定
PersonDto中的ID与返回的Person对象中的相同ID对应吗?你确定它不为空吗? 2.你确定你没有从另一个事务方法调用method2,因此事务还没有结束,也许method3()是在第一个事务提交之前从另一个事务调用的? -
是的,我敢肯定,在 method3 中检索它之前,我有一个日志。此外,它大部分时间都有效,大约 1% 的时间会失败,通常是在执行速度超快时。关于事务,在 StackTrace 中没有其他带有 @Transactional 注释的方法。谢谢!
标签: java postgresql jpa transactions spring-data