Reputation: 2815
I have a process that iterates through a list of events and saves them to a table. If a particular event throws an exception, I need to be able to rollback that event's transactions with the database without effecting the flow through the other events.
To achieve this, I have the following setup:
public class EventService
{
public void processEvents()
{
List<Event> events = getEvents();
foreach(Event event : events)
{
try
{
processEvent(event);
}
catch(Exception e)
{
// log the exception and continue processing additional events
}
}
}
@Transactional
public void processEvent(Event event)
{
// Process event and insert rows into database
// Some event will throw a runtime exception
}
}
However, this is not rolling back the event if there is an exception thrown.
Is there a way to achieve what I'm trying to do here?
Upvotes: 2
Views: 1298
Reputation: 19905
You could also try a "pure Java" approach, if "manual" rollback is possible:
public void processEvents()
{
List<Event> events = getEvents();
boolean rollback = false;
for (Event event : events)
{
try
{
processEvent(event);
}
catch (Exception e)
{
// log the exception and continue processing additional events
rollback = true;
}
finally
{
if (rollback)
{
... // "Manually" roll back the transaction
rollback = false; // Deactivate rolling back
}
}
}
}
Upvotes: 0
Reputation: 4989
If you call a method within the same class, Spring AOP does not have a chance to intercept the method. Therefore the @Transactional
annotation is ignored. Trying moving the processEvent
method to another class that is Spring injected.
Upvotes: 5
Reputation: 3046
You will need to define your process Event with Propagation.REQUIRES_NEW and rollbackFor = Exception.class as below:
@Transactional(propagation=Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
public void processEvent(Event event)
{
// Process event and insert rows into database
// Some event will throw a runtime exception
}
Upvotes: 5
Reputation: 3176
Have you tried rollbackFor value on your transaction method?
@Transactional(rollbackFor = YourException.class)
public void processEvent(Event event)
{
// Process event and insert rows into database
// Some event will throw a runtime exception
}
Upvotes: 1