@Transaction не работает для нескольких внутренних методов одного класса или при вызове методов других классов - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть метод, который аннотирован @Transactional, который внутренне вызывает несколько внутренних методов для одного и того же класса, который внутри них может вызывать или не вызывать какие-либо другие внешние методы обслуживания. Когда он вызывает метод внешнего класса обслуживания, он работает для 1 метода, что означает его откат, но тот же сервис при вызове другого метода того же класса [только для внешнего класса обслуживания], это не откат, может кто-нибудь помочь мне здесь.

  @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
}

Может кто-нибудь помочь мне здесь? Также я хотел бы узнать больше о правильном использовании транзакций, таких как множественные внутренние методы одного класса или множественные внутренние методы другого класса, вызываемые прокси-классом и так далее.

1 Ответ

0 голосов
/ 05 ноября 2019

Единственное структурное различие между вызовами doSomething1 и doSomething2 состоит в том, что первый вызывается формой внутри встроенной функции. (который передается потоку, который может быть реализован каким-то причудливым асинхронным способом.)

Что произойдет, если вы реорганизуете свой код следующим образом:

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

(Если это работает, рефакторинги другой метод, есть хороший шанс, что task1 и task2 не откатятся, потому что details.getDetails() имеет аналогичную реализацию.)

...