Java 在相同和不同的服务中调用@Transactional和non-Transactional方法时如何回滚事务?

Java 在相同和不同的服务中调用@Transactional和non-Transactional方法时如何回滚事务?,java,spring,spring-data-jpa,spring-data-rest,distributed-transactions,Java,Spring,Spring Data Jpa,Spring Data Rest,Distributed Transactions,我使用的是SpringDataREST和SpringJPA。我有一个方法更新一个数据库表 @Autowired InvoiceClient; @Override @Transactional public String doBilling(String x){ //get date from TableOne Bill bill = billsRepository.getBill(x); if(bill.isPaid()){ generateInvoice(); } bill.setP

我使用的是SpringDataREST和SpringJPA。我有一个方法更新一个数据库表

@Autowired InvoiceClient;

@Override
@Transactional
public String doBilling(String x){
//get date from TableOne
Bill bill = billsRepository.getBill(x);
if(bill.isPaid()){
    generateInvoice();
}
bill.setPaymentDate(new Date());
return "SUCCESS";
}
generateInvoice是从其他服务调用@Transactional方法的非事务性方法

public void generateInvoice(){
    invoiceClient.generateInvoice();//this is @Transactional, make changes in TableTwo
}
如果generateInvoice方法中出现任何异常,整个事务将回滚。 现在我想再添加一个方法,该方法将包含账单编号列表。我在循环中调用doBilling方法对所有账单进行计费

@Override
@Transactional(readOnly = false, rollbackFor = {Throwable.class}, propagation = Propagation.REQUIRED)
public String doBillingForAll(List<String> tx){
    for(String x: tx){
         doBilling(x);
    }
}
@覆盖
@事务(readOnly=false,rollboor={Throwable.class},propagation=propagation.REQUIRED)
公用字符串doBillingForAll(列表tx){
用于(字符串x:tx){
多巴酚丁胺(x);
}
}
但现在,如果doBilling方法中出现任何异常,所有setPayment方法都将回滚,但generateInvoice将保持不变。
我还想回滚generateInvoice。我怎么做呢?

您不需要定义
rollboor={Throwable.class}
。 默认情况下,所有
RuntimeException
在使用
@Transactional
时执行回滚

可能是因为您使用的是中间非
@Transactional
注释方法,所以主事务被挂起,并创建了一个嵌套的事务


尝试将
@Transactional
放入您的
public void generateInvoice()
中,然后进行
传播。所需的
应与发票回滚一起应用

我尝试在generateInvoice()方法中添加@Transactional,但仍不起作用。另外,我的服务类已经用@Transational(readOnly=false)注释了。invoiceClient.generateInvoice()调用一个接口,该接口反过来调用generateInvoice()方法的实现。我的猜测是,由于这个原因,正在为此方法调用创建一个新事务。您是否可以尝试在
generateInvoice()
上使用
@Transactional(propagation=propagation.SUPPORTS)
,并告诉我发生了什么?如果不存在事务,则propagation.SUPPORTS执行非事务性。但是,在这种情况下,类已经用@Transaction进行了注释,那么它会有什么不同呢?您将检查是否已经创建了另一个事务。如果你有一个例外,这意味着其他地方有一些问题。