简体   繁体   中英

How to rollback transaction on calling @Transactional and non-Transactional method in same and different Service?

I am using spring data rest and Spring JPA. I am having one method which update one database table.

@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 is non Transactional method which calls @Transactional method from other service.

public void generateInvoice(){
    invoiceClient.generateInvoice();//this is @Transactional, make changes in TableTwo
}

In case of any exception in generateInvoice method whole transaction is rolled back. Now I want to add one more method which will have list of bill numbers. I call doBilling method in loop to do billing for all the bills.

@Override
@Transactional(readOnly = false, rollbackFor = {Throwable.class}, propagation = Propagation.REQUIRED)
public String doBillingForAll(List<String> tx){
    for(String x: tx){
         doBilling(x);
    }
}

But now in case of any exceptions in doBilling method, all the setPayment methods are getting rolled back but generateInvoice is persisted. I want to rollback generateInvoice also. How can I do it?

You don't need to define a rollbackFor = {Throwable.class} . By default all RuntimeException do a rollback when using @Transactional .

It can be that because you are using and intermediate non @Transactional annotated method, the main Transaction is suspended and a nested one is created.

Try to put @Transactional in your public void generateInvoice() then Propagation.REQUIRED should be applied with rollback of your invoices

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM