Spring @Transactional 不在 MS 上开始新事务 SQL

Spring @Transactional does not begin new transaction on MS SQL

我在 Spring 使用 @Transactional 注释启动时遇到事务问题。最新的 Spring 已连接到 MS SQL 数据库。

我有以下服务,它根据一些标准定期执行事务方法:

@Service
public class SomeService {

    SomeRepository repository;

    public SomeService(SomeRepository someRepository) {
        this.repository = someRepository;
    }

    @Scheduled(fixedDelayString="${property}") //10 seconds
    protected scheduledIteration() {
    
         if(something) {
             insertDataInNewTransaction(getSomeData());
         }

    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    protected void insertDataInNewTransaction(List<Data> data) {

       //insert data to db
       repository.saveAll(data);

      //call verify proc
      repository.verifyData();
      
    }

}

该算法应该处理数据,将它们插入 table 并执行检查(数据库过程)。如果过程抛出异常,事务应该被回滚。我敢肯定,该过程不会执行事务的提交。

我面临的问题是,调用该方法不会开始新的事务(或开始但它是自动提交的),因为我尝试了以下操作:

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
protected void insertDataInNewTransaction(List<Data> data) {

     int counter = 0;
     for(Data d : data) {
         repository.save(d);
         counter++; 

         //test
         if(counter == 10) {
             throw new Exception("test");

         }
     }
    

}

执行测试方法后,前 10 行保留在 table 中,它们应该被回滚。在调试期间我注意到,在循环中调用 repository.save() 会插入到 table 外部事务,因为我可以在调试器位于下一行时看到来自 DB IDE 的行。这给了我一个想法,问题是由自动提交引起的,因为它是 MS SQL 默认值。所以我尝试添加以下属性,但没有任何区别:

spring.datasource.hikari.auto-commit=false
spring.datasource.auto-commit=false

我做错了什么吗?

如果使用Spring Proxy AOP,那么需要将方法insertDataInNewTransaction转为public.

请记住,如果方法是 public,但它是从同一个 bean 调用的,它不会创建新事务(因为 spring 代理不会被调用)。

简答:

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void insertDataInNewTransaction(List<Data> data) {

   //insert data to db
   repository.saveAll(data);

  //call verify proc
  repository.verifyData();
  
}

但如果您真的需要一个新的单独交易,请使用 Propagation.REQUIRES_NEW 而不是 Propagation.REQUIRED