为了账号安全,请及时绑定邮箱和手机立即绑定

Transactional 注释在使用 try catch 的 for 循环中不起作用

Transactional 注释在使用 try catch 的 for 循环中不起作用

慕哥9229398 2022-06-08 17:12:26
我的问题如下。伪代码代码如下: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");  }我在这里做什么:在 中迭代一个列表rollBackTestMainMethod()。发送一个列表项rollBackTestSubMethod()并执行 3 保存操作。如果全部保存完成则返回真响应,否则抛出异常。中rollBackTestMainMethod(),在得到响应或异常后,在每个项目上添加错误或成功值。它将此项添加到名为 的新列表中responseList。在所有操作之后,它会将其作为响应发送回来。我的问题:从rollBackTestSubMethod()它抛出后不会回滚,因为它是从 try catch 块调用的。如果我想强制回滚,TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();那么它将回滚所有项目以进行任何抛出/异常。在这里,我只想回滚投掷物品而不是所有物品。此方法在 Spring bean 中我正在通过spring data jpa将数据保存到我的关系数据库中
查看完整描述

2 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

这是因为您正在@Transactional从同一个 bean 中调用方法。


@Transactional仅适用于在 spring 创建的代理上调用的方法。这意味着,当您创建一个@Service或其他 bean 时,从外部调用的方法将是事务性的。如果从 bean 中调用,什么都不会发生,因为它不通过代理对象。


最简单的解决方案是将方法移至另一个@Service或 bean。如果你真的想将它保存在同一个组件中,那么你需要调用它,以便它被 spring AOP 包装在代理中。你可以这样做:


private YourClass self;


@Autowired

private ApplicationContext applicationContext;


@PostConstruct

public void postContruct(){

    self = applicationContext.getBean(YourClass.class);

}

然后调用方法self将导致打开事务。


查看完整回答
反对 回复 2022-06-08
?
慕仙森

TA贡献1827条经验 获得超8个赞

标记非公共方法 @Transactional 既无用又具有误导性,因为 Spring 没有“看到”非公共方法,因此没有为它们的正确调用做准备。Spring 也没有为它调用的方法调用的方法做准备。

因此,标记私有方法,例如,@Transactional 只有在方法实际上被写入@Transactional 时才会导致运行时错误或异常。


查看完整回答
反对 回复 2022-06-08
  • 2 回答
  • 0 关注
  • 288 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号