2

I have sequence of table data creation in transaction, using springboot, java, jpa and hibernate sequence shown below. Database used is Oracle

  1. Place order - insert into order details_table
  2. Process Payment - insert into payment_info table
  3. Error Message(info, warning, error) - insert into error_message table

I am inserting error messages in error_message table if any error occurs(info, warning, error).
My info and warning message get persisted into error_message if no error occurs during the processing of the request. But if there is an error, I am throwing an error from code to rollback the transaction, its working but my error_message also get rollback.

I want to rollback details_table and payment_info but not the error_message, I want them to be persisted.

How I can achieve the same?

balias
  • 499
  • 1
  • 4
  • 17
SSK
  • 3,444
  • 6
  • 32
  • 59
  • Use PL/SQL procedure with [pragma autonomous_transaction](https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/autotransaction_pragma.htm) to save data into error_message table – Dornaut Oct 09 '20 at 05:29
  • 1
    use `@Transactional(propagation = Propagation.REQUIRES_NEW) ` on save error_message method ,https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html#tx-propagation-requires_new – divilipir Oct 09 '20 at 06:43

1 Answers1

1

Use two different transactions.

The default transaction propagation is REQUIRED, when calling your @Transactional annotated method without a transactional context, a new transaction will be started but if there's already a transaction in place, the transaction will be joined, ending up with a single transaction. In case of rollback, all operations will be rollbacked as they belong to the same transaction.

Change the transaction propagation to REQUIRES_NEW in order to always force starting a new transaction (instead of joining it if there's one). This will allow you to commit the error messages transaction independently from the payment info.

@Transactional
public void placeOrder(Order oder) {
  // process order
  
  paymentGateway.processPayment();

  // save order <- an exception here will rollback the current 
  // transaction but not the one in PaymentGateway which is independent
} 

// In PaymentGateway
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processPayment() {
  // process payment
  // insert error messages
}

Further reading: Understanding PROPAGATION_REQUIRED. Make sure you also understand how exceptions affect transactions.

Sergi Almar
  • 8,054
  • 3
  • 32
  • 30