我的问题如下。 下面给出了伪代码:
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;
}
我在这里做什么:
rollBackTestMainMethod()
中的列表。在rollBackTestSubMethod()
中发送一个列表项并执行3保存操作。rollBackTestMainMethod()
中,获得响应或异常后,它将在每个项目上添加错误或成功值。responseList
的新列表中。在完成所有操作后,它会将其作为响应发送回去。 我的问题:
rollBackTestSubMethod()
抛出之后,它不会回滚,因为它是从try catch块中调用的。TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
强行回滚,则它将针对所有抛出/异常回滚所有项目。我的进口商品:
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
答案 0 :(得分:7)
这是因为您正在同一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
上调用方法将导致打开交易。
答案 1 :(得分:0)
标记非公共方法@Transactional既无用又具有误导性,因为Spring不会“看到”非公共方法,因此没有为其适当的调用做任何准备。 Spring也不为它所调用的方法所调用的方法做准备。
因此,标记一个私有方法,例如,@ Transactional仅在该方法实际写为@Transactional时才会导致运行时错误或异常。