多JPA事务内部的一种方法

时间:2019-12-04 00:13:34

标签: spring-boot jpa transactions entitymanager

我有一个示例,需要通过条件外部循环回滚一些内部循环方法。 我使用EntittyManager和@Transactional。 因为循环中的逻辑很复杂,所以我不想引入2循环。 如何实现回滚,提交?

@Service
@Transactional
public class StudentServiceImpl implement 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)
     }

1 个答案:

答案 0 :(得分:0)

从问题陈述中可以看出

  

method1(),method2()和method3()调用应在当前txn内运行。

     

method4()和method5()应该在各自独立的txn上运行。

当method1()返回false时,将执行中断,并且RuntimeException将回滚通过method1()事务插入到该点的所有内容。

method4()和method5()数据将保留下来,因为它们处于它们自己的独立事务中。

了解更多信息

  

PROPAGATION_REQUIRES_NEW = 3;如果DataSourceTransactionObject T1为   方法M1已启动,正在执行中(执行方法   M1)。如果另一个方法M2开始执行,则T1被挂起   使用新DataSourceTransactionObject T2的方法M2的持续时间   M2.M2在自己的交易环境中运行

还要注意,自我调用(目标对象内的方法调用)不会导致事务。您需要对method4()和method5()上的事务进行自我注入才能工作。如下

         @Service @Transactional
            public class StudentServiceImpl implements StudentService {

               @Autowired
               private StudentService self;   //self injection ;

               @Transactional(propagation= Propagation.REQUIRES_NEW)
               public boolean execute(List<ADto> adtoList) {
                boolean a = true;
                for(ADto dto : adtoList) {
                  boolean a = method1(dto); // uses the current txn.
                  if(a == false) {
                      break;
                  }
                  self.method4(); // do insert data into D, E table
                  self.method5(); // do update into F table
                }
                if(!a) {
                  throw new RuntimeException("Rollback Txn for method1");
                }
               }


               @Transactional(propagation= Propagation.REQUIRES_NEW)
               public void method4() {

               }

               @Transactional(propagation= Propagation.REQUIRES_NEW)
               public void method5() {

               }
            }

method4()和method5()用@Transactional(propagation = Propagation.REQUIRES_NEW)注释并在代理上调用

还可以从文章https://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial中了解有关REQUIRES_NEW行为的信息