@ Transaction不适用于同一类的多个内部方法或在另一个类的调用方法中使用

问题描述 投票:0回答:1

我有一个用@Transactional注释的方法,该方法内部为同一类调用多个内部方法,这些内部方法可能会或可能不会调用任何其他外部服务方法。当它调用外部服务类方法时,它正在为一种表示回滚的方法工作,但是当调用同一类的另一个方法(仅外部服务类)时,同一服务却没有回滚,任何人都可以在这里帮助我。

  @Transactional 
  public void processPayments(PaymentRequest request) { 
    request.getDetails.forEach(payment -> {
                method1(payment);
    });
   // when doSomething1() is success , then its calling below method ,
   externalService.doSomething2();// when it api fails , it is rollbacking properly , the process of calling is exactly same. Howcome this is rollbacking not dosomething1() is not rollbacking ?

}

private void method1(PaymentDetails details){
    details.getDetails.forEach(detailedPayment -> {
                method1_1(detailedPayment);
            });

    task3();
}

private void method1_1(DetailedPayment detailedPayment){
    roundPayment();
    task1();
    task2();
}

private void roundPayment(){

}

private SomeObject task1(SomeObjet object){
    // update object with if conditions 
    repository.save(object);
}

private SomeObject task2(){
    // update object with if conditions 
    repository.save(object);
}


private SomeObject task3(){
    // repository.save(updateSomeObject(someObject));
    // externalService.doSomething1(double val1 , double val2); // this is another service , which also uses another service , which uses restTemplate to call external service. , if http status is other than 200 , i am throwing ExternalAPICall Exception , which should roll back full transaction starting from processPayments method 
    // its not roll backing 
}

private void updateSomeObject(SomeObject object){
    // update object based on few if conditions
}

有人可以在这里帮助我吗?我也想了解更多有关正确使用事务的信息,例如同一个类的多个内部方法,或由代理类调用的另一个类的多个内部方法,等等。

spring spring-boot spring-data-jpa jpa-2.0 spring-transactions
1个回答
0
投票

调用doSomething1doSomething2之间的唯一结构差异是,第一个被调用为内联函数中的form。 (将其传递到流,该流可以以某种花哨的异步方式实现。)

如果您以这种方式重构代码会发生什么:

  @Transactional 
  public void processPayments(PaymentRequest request) { 
    for(PaymentDetails details: request.getDetails()) {
      method1(details);
    }
    externalService.doSomething2();
  }

((如果可行,也重构另一种方法,很有可能task1和task2都不会回滚,因为details.getDetails()具有类似的实现。)

© www.soinside.com 2019 - 2024. All rights reserved.