Spring @事务不适用于同一类的多个内部方法,或者在调用其他类的方法时不适用

Spring @事务不适用于同一类的多个内部方法,或者在调用其他类的方法时不适用,spring,spring-boot,spring-data-jpa,jpa-2.0,spring-transactions,Spring,Spring Boot,Spring Data Jpa,Jpa 2.0,Spring Transactions,我有一个用@Transactional注释的方法,它在内部为同一个类调用多个内部方法,这些内部方法可能调用也可能不调用任何其他外部服务方法。当它调用外部服务类方法时,它为1个方法工作,意味着它回滚,但当调用同一类的另一个方法[仅限外部服务类]时,它是相同的服务,它不是回滚,这里有人能帮我吗 @Transactional public void processPayments(PaymentRequest request) { request.getDetails.forEac

我有一个用@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
}

有人能帮我吗?此外,我还想了解更多关于事务性方法的正确使用,比如同一类的多个内部方法,或者被代理类调用的另一个类的多个内部方法等等

调用
doSomething1
doSomething2
之间唯一的结构区别在于,第一个函数是在内联函数中以形式调用的。(它被传递到一个流,可以通过某种奇特的异步方式实现。)

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

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

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

您使用的是哪一个数据库,不是所有的东西都被回滚或部分回滚?它只会回滚数据库中的内容,通过HTTP请求所做的修改不会回滚!。Mysql,如果HTTP请求返回的不是200201,我必须从第一个方法开始回滚整个事务,我依赖于外部调用。我可以先调用外部,然后调用本地java代码,但要求完全执行本地java代码,得出最终值,然后使用计算值调用外部服务,这一切都很好,然后只提交事务。我现在正在调用2HTTP服务,它可能也会增加。外部服务有自己的数据库,我的应用程序有自己的数据库。您不能回滚外部服务,您不能(从应用程序)控制这些服务。如果您使用的是MySQL,请确保您使用的是InnoDB表,而不是MyISAM表!。是的,我同意我没有控制权。如果api调用没有得到200,我只想回滚事务。若不是200,我将抛出自定义异常,它将回滚事务。它适用于1个方法,但不适用于同一类的另一个方法。我只使用innoDB表您只有一个公共方法,所以不确定您正在考虑哪种其他方法?同时从同一类中调用同一方法将忽略
@Transactional
,因为它没有通过代理。还要确保您的自定义异常是
运行时异常
,或者您的
@Transactional
配置为在自定义异常(如果它不是
运行时异常
)上回滚。