@Transactional方法在try-catch包围时不回滚

时间:2014-01-09 15:34:49

标签: java spring transactional

我有一个迭代事件列表并将它们保存到表中的进程。如果特定事件抛出异常,我需要能够使用数据库回滚该事件的事务,而不会影响其他事件的流程。

为实现这一目标,我有以下设置:

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
    }
}

但是,如果抛出异常,则不会回滚事件。

有没有办法实现我在这里要做的事情?

4 个答案:

答案 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
    }

Refer Spring Transcation

答案 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
            }
        }

    }
}