gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 10:08:42 25 4
gpt4 key购买 nike

我的问题如下。 伪代码如下:

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. 如果全部保存完成则返回真响应,否则抛出异常。
  3. rollBackTestMainMethod()中,在得到响应或异常后,在每一项上添加错误或成功值。
  4. 正在将此项添加到名为 responseList 的新列表中。在所有操作之后,它会将此作为响应发回。

我的问题:

  1. rollBackTestSubMethod() 抛出后,它不会回滚,因为它是从 try catch block 调用的。
  2. 如果我想通过 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 强制回滚,那么它将回滚任何抛出/异常的所有项目。
  3. 这里我只想回滚 throw 元素而不是所有元素。
  4. 这个方法在 spring bean 中
  5. 我正在通过 spring data jpa 将数据保存到我的关系数据库中

我的导入:

import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

最佳答案

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

@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 上调用方法将导致打开一个事务。

关于java - Spring @Transactional 注释在使用 try catch 的 for 循环中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54567573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com