代码之家  ›  专栏  ›  技术社区  ›  Md. Sajedul Karim

Spring@Transactional anotion不能在for循环中使用try-catch

  •  1
  • Md. Sajedul Karim  · 技术社区  · 7 年前

    下面是我的问题。 伪码如下所示

    public Object rollBackTestMainMethod(List<Object> list) {
    
      List<Object> responseList = new ArrayList<>();
    
      for(Object item:list){
    
        try{    
          Boolean isOperationSuccess = rollBackTestSubMethod(item);
          if (isOperationSuccess==null || !isOperationSuccess){
            item.addError("Operation failed");
            item.addSuccess(false);
          } else {
            item.addError(null);
            item.addSuccess(true);
          }
    
        } catch(Exception exception) {
          item.addError(exception.getMessage());
          item.addSuccess(false);
        }
    
        responseList.add(item);
      }
    
      return responseList;
    }
    
    @Transactional(rollbackFor = {Exception.class, SQLException.class})
    private Boolean rollBackTestSubMethod(Object listItem){
    
      Long value1=save(listItem.getValue1());
      if(value1==null){
        throw new Exception("Error during save 1");
      }
    
      Long value2=save(listItem.getValue2());
      if(value2==null){
        throw new Exception("Error during save 2");
      }
      Long value3=save(listItem.getValue3());
      if(value3==null){
        throw new Exception("Error during save 3");
      }
    
      return Boolean.TRUE;
    }
    

    我在这里做的是:

    1. 在中迭代列表 rollBackTestMainMethod() . 正在发送一个列表项 rollBackTestSubMethod() 执行3保存操作。
    2. 回滚TestMainMethod() ,在获得响应或异常后,它将在每个项上添加错误或成功值。
    3. responseList . 在所有操作之后,它会将此作为响应发送回去。

    我的问题:

    1. 在从 回滚测试子方法()
    2. 如果我想通过 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    3. 在这里,我想回滚只有抛出项目,而不是所有的项目。
    4. 这种方法的优点是在一个springbean中
    5. 我正在通过将数据保存到关系数据库中 弹簧数据jpa

    我的导入:

    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.transaction.interceptor.TransactionAspectSupport;
    
    1 回复  |  直到 6 年前
        1
  •  12
  •   Andronicus    7 年前

    @Transactional 来自同一bean的方法。

    @事务性 仅适用于在spring创建的代理上调用的方法。意思是,当你创建一个 @Service 或者其他bean,从外部调用的方法将是事务性的。如果从bean内部调用,什么也不会发生,因为它不会通过代理对象。

    最简单的解决方案是将该方法移到另一个方法 或者豆子。如果您真的想将它保存在同一个组件中,那么您需要调用它,这样它就可以被springaop包装在proxy中。你可以这样做:

    private YourClass self;
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @PostConstruct
    public void postContruct(){
        self = applicationContext.getBean(YourClass.class);
    }
    

    然后调用上的方法 self

        2
  •  0
  •   Khalifa Abd El Aziz    6 年前

    将一个非公共方法标记为@Transactional既没用又容易引起误解,因为Spring没有“看到”非公共方法,因此没有为它们的正确调用做任何准备。Spring也没有为它所调用的方法调用的方法做准备。