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.
Asked
Active
Viewed 897 times
1

Simone Sorgon
- 155
- 1
- 14
-
Is your code encapsulated in service builder or external to it? E.g. can you provide a [mcve]? – Olaf Kock Apr 21 '21 at 19:00
-
is inside a service builder – Simone Sorgon Apr 22 '21 at 07:37
1 Answers
2
There are three cases:
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.
If your code is in a MVCActionCommand, you can use the BaseTransactionalMVCActionCommand as the parent class and implement your code in the doTransactionalCommand method.
- Your code will be wrapped in a new transaction
- For more information see: https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/portlet/bridges/mvc/BaseTransactionalMVCActionCommand.java
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);

jorgediaz-lr
- 942
- 6
- 13
-
But the methods in LocalServiceImpl don't have to be private ? Because i create one method that inside there are calls to three private method (delete,add,add).. but if the delete it's ok, and first add no, i lost any data in database.. – Simone Sorgon Apr 22 '21 at 07:14
-
You are free in your choice of parameters - e.g. you can create one `*LocalServiceImpl` method like `updateData(List addTheseObjects, List deleteTheseObjects)` and implement this method as a loop through the objects. `updateData` will open the transaction, and it will be propagated to the following `add` and `delete` calls within `updateData's` implementation (until you return from `updateData`. – Olaf Kock Apr 22 '21 at 07:52
-
My ancient memory says that transactions are opened automatically based on method names - can you confirm or deny, @Jorge? (e.g. `add*`, `update*`, `delete*` would be candidates, while `doSomething()`isn't) – Olaf Kock Apr 22 '21 at 08:04
-
1Yes, thats true, @OlafKock, by default add*, update* and delete* are considered transactional. I think that other methods are annotated with the `@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)` annotation, so they only use the transaction if it is already created in the parent one, but they don't create a new one, as readOnly is true – jorgediaz-lr Apr 22 '21 at 09:28
-
I create method `public void updateContacts(List
users,List – Simone Sorgon Apr 22 '21 at 13:23contacts)` that inside call three methods to (delete, add, add) but if first add isn't ok, i lost the date because delete it was ok -
Method delete it jus a for to delete all concacts. Methods add to add different type of contacts – Simone Sorgon Apr 22 '21 at 13:24