我有一个迭代事件列表并将它们保存到表中的进程。如果特定事件抛出异常,我需要能够使用数据库回滚该事件的事务,而不会影响其他事件的流程。
为实现这一目标,我有以下设置:
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
}
}
但是,如果抛出异常,则不会回滚事件。
有没有办法实现我在这里要做的事情?
答案 0 :(得分:5)
您需要使用Propagation.REQUIRES_NEW和rollbackFor = Exception.class定义您的流程事件,如下所示:
@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
}
答案 1 :(得分:5)
如果在同一个类中调用方法,Spring AOP没有机会拦截该方法。因此,@Transactional
注释将被忽略。尝试将processEvent
方法移动到另一个Spring注入的类。
答案 2 :(得分:1)
您是否尝试过对事务方法的rollbackFor值?
@Transactional(rollbackFor = YourException.class)
public void processEvent(Event event)
{
// Process event and insert rows into database
// Some event will throw a runtime exception
}
答案 3 :(得分:0)
如果可以“手动”回滚,你也可以尝试“纯Java”方法:
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
}
}
}
}