How can i do a Transactional method in Liferay 7.3?

1.1k views Asked by At

I create a scheduler that in the same transaction delete rows in DB and insert new rows after delete. But if the adding of rows fails, I lost my data because the delete was correctly. How I can delete and add with the same transaction to avoid losing data in case of errors? I want to do a delete and two different adds in the same table.

1

There are 1 answers

6
jorgediaz-lr On

There are three cases:

  1. If your code were everything starts is in a method a LocalServiceImpl class generated by service builder:

    • Liferay automatically creates a transaction that begins in the first method called in the first LocalServiceImpl and is propagated in the internal calls that that method does to the methods other LocalServiceImpl classes.
    • So the idea is to have a entry point in a LocalServiceImpl method where Liferay will automatically start the transaction, and from that method, call the other LocalServiceImpl methods that must be executed in the same transaction.
    • Note: by default only the methods that change data (add, update, delete) are creating a new transaction.
  2. If your code is in a MVCActionCommand, you can use the BaseTransactionalMVCActionCommand as the parent class and implement your code in the doTransactionalCommand method.

  3. If your code is outside of the LocalServiceImpl classes, you can always manually create a transaction using TransactionInvokerUtil:

     import com.liferay.portal.kernel.transaction.*;
     import com.liferay.portal.kernel.service.*;
     import java.util.concurrent.*;
    
     private _invokeTransactionally(Callable callable)
         throws Throwable {
    
         Class<?>[] rollbackForClasses = new Class<?>[1];
    
         rollbackForClasses[0]=Exception.class;
    
         try {
             TransactionInvokerUtil.invoke(
                 TransactionConfig.Factory.create(
                     Propagation.REQUIRED, rollbackForClasses), callable);
         }
         catch(Exception e) {
              // handle the exception
         }
     }
    
     Callable callable = new Callable<Void>() {
         Void call() throws Exception {
              // here insert your code
    
              return null;
         }
     }
    
    • Your code should go inside the Callable class.
    • To execute it: _invokeTransactionally(callable);