我有一个示例,需要通过条件外部循环回滚一些内部循环方法。我使用EntittyManager和@Transactional。因为循环中的逻辑很复杂,所以我不想引入2循环。如何实现回滚,提交?
@Service
@Transactional
public class StudentServiceImpl extends StudentService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean execute(List<ADto> adtoList) {
boolean a = true;
for(ADto dto : adtoList) {
boolean a = method1(dto); // call to sub method2, method3 to insert data into A, B table
if(a == false) {
break;
}
method4(); // do insert data into D, E table
method5(); // do update into F table
}
if(a == false) {
// need rollback all inserted data in A, B table which is inserted in method1, method2, method3 (of all loop element)
// still commit all inserted data at method4(), method5() (of all loop element)
}
从问题陈述看来,
method1()调用应在一个事务中独立运行。
阅读更多内容
PROPAGATION_REQUIRES_NEW = 3;如果DataSourceTransactionObject T1为方法M1已启动,正在执行中(执行方法M1)。如果另一个方法M2开始执行,则T1被挂起使用新DataSourceTransactionObject T2的方法M2的持续时间M2.M2在其自己的事务上下文中运行
还请注意,自调用(目标对象内的方法调用)不会导致事务。您需要对method1()上的事务进行自我注入才能工作。如下所示
@Service @Transactional
public class StudentServiceImpl extends StudentService {
@Autowired
private StudentService self; //self injection ;
@Transactional(propagation= Propagation.REQUIRES_NEW)
public void execute(List<ADto> adtoList) {
//...
}
@Transactional(propagation= Propagation.REQUIRES_NEW)
public void method1() {
//call self.methodFoo() rather than this.methodFoo()
self.methodFoo();
}
}
如果method1()用@Transactional(propagation = Propagation.REQUIRES_NEW)注释并在代理上调用,您将能够实现您的要求。
也从文章https://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial中了解了REQUIRES_NEW行为