首页 > 解决方案 > 强制不同的 Spring Repositories 使用相同的事务

问题描述

我正在做一个项目,我想使用非常具体的事务传播策略。该数据库有两组表,活动表和存档表。每组表都是用它自己的实体和接口来实现的CrudRepository<T, ID>。目标是将一组实体插入到活动表中,并在单个事务中将活动表中的所有数据插入归档表中。表中的实体不一样,会有不同的表结构。

给定两个类似于表单的独立存储库

public interface FooRepository extends CrudRepository<Foo, Integer>
public interface FooArchiveRepository extends CrudRepository<FooArchive, Integer>

和类似的实现

@Autowired FooRepository fooRepo;
@Autowired FooArchiveRepository fooArchiveRepo;
@Autowired BarService barService;
List<Foo> newData = barService.doThing();
fooRepo.saveAll(newData);
// fooData is a list of FooArchive from earlier
fooArchiveRepo.saveAll(fooData);

目标是拥有fooRepo.saveAll(newData)fooArchiveRepo.saveAll(fooData)保证在单个数据库事务中执行。Spring 的默认事务传播在同一个物理事务中执行Required不同Transactional的方法 - 这适用Transactional于应用程序上下文中的所有方法,还是仅适用于每个实体?

标签: javaspringspring-bootspring-data-jpa

解决方案


将保存调用包装到一个新方法中并使用 @Transactional 注释该方法

@Transactional
public void saveAll(){
  fooRepo.saveAll(newData);
  // fooData is a list of FooArchive from earlier
  fooArchiveRepo.saveAll(fooData);
}

默认情况下(PROPAGATION_REQUIRED)它会将内部事务执行到同一个事务中。请参阅 https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/images/tx_prop_required.png


推荐阅读