我很难找到关于这个主题的文件。我已经看过Spring official transactionnal handling documentation,还有一些SO帖子指向一个是的,但这不是我在实践中看到的。
考虑Sping Boot 应用程序,使用@EnableTransactionManagement
,@EnableJpaRepositories
(使用Hibernate和Postgres)。我有以下代码:BusinessService
:
@Transactional
public save(BuildingDTO dto) {
var building = Building.from(dto);
var apartments = Apartment.from(dto);
this.buildingRepository.save(building);
this.saveAllJdbc(apartments);
}
private saveAllJdbc(List<Apartment> apartments) {
String insertQuery = "...";
jdbcTemplate.batchUpdate(
insertQuery,
apartments,
100,
(ps, apartment) -> // set ps values
);
}
存储库定义为BuildingRepository extends CrudRepository<Building, UUID>
,这意味着保存方法是事务性的。
今天我的问题是saveAllJdbc
触发了外键约束,说引用的建筑不存在。这意味着它不知道当前事务。
我通过只使用Spring CrudRepository
方法或只使用JdbcTemplate
方法使其工作,在这两种情况下,事务都按照文档中的定义进行处理。
Spring Repository默认实现和JdbcTemplate方法应该共享事务上下文吗?或者这是一个已知的限制?
1条答案
按热度按时间vshtjzan1#
这与事务无关,与JPA的工作方式无关。
当您告诉JPA保存数据时,它不会这样做。或者至少它可以选择不这样做。相反,它只会保留对数据的引用,并最终保存它。* 最终 * 通常意味着在交易结束时。
另一方面,
JdbcTemplate
没有什么花哨的东西,只执行SQL语句。正如奥利弗Drotbohm所写的,您可以通过使用
JpaRepository.saveAndFlush()
而不是save()
触发flush事件来解决这个问题。