强制不同的 Spring Repositories 使用相同的事务

Leo*_*Leo 5 java spring spring-data-jpa spring-boot

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

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

public interface FooRepository extends CrudRepository<Foo, Integer>
public interface FooArchiveRepository extends CrudRepository<FooArchive, Integer>
Run Code Online (Sandbox Code Playgroud)

和类似的实现

@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);
Run Code Online (Sandbox Code Playgroud)

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

Adi*_*lea 6

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

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

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