Spring嵌套的@Transactional方法和回滚

8
我有一个@Service类,其中有一个@Transactional方法,该方法调用同一类中的另一个@Transactional方法。我正在测试它的回滚行为,并发现它无法正常工作。代码大致如下:
@Service
public class DefaulService implements ervice
{
    @Transactional
    public void methodOne()
    {
        methodTwo();

            //question edited
            //this seems to be the problem
            this.serviceDAO.executeUpdateOperation();

        //test rollback
        throw new RuntimeException();
    }

    @Transactional
    public void methodTwo()
    {
        //DAO stuff
    }
}

运行methodOne后,我检查了数据库,发现更改已经生效,尽管日志显示“JDBCTransaction - rollback”。
如果我单独调用methodTwo并在结尾处添加异常,则更改会正确地回滚。
有没有办法使methodOne正确回滚在嵌套的@Transactional调用期间发生的更改? 我认为REQUIRED的默认传播应该可以实现这一点,但似乎并没有起作用。谢谢
更新
好吧,我刚刚注意到另一件事。 在抛出异常之前,我正在调用服务的DAO并通过“executeUpdate”执行手动更新。 如果我注释掉这一行,则嵌套的回滚有效。 因此,问题实际上是调用DAO并运行executeUpdate查询。 但是这不应该在当前事务内运行吗?

你是否知道在从methodOne()调用methodTwo()时,前者上的@Transactional注解会被忽略?请参阅我的文章以获取更多详细信息。然而,这并不会导致你的问题,但了解这一点仍然很有价值。 - Tomasz Nurkiewicz
是的,但由于MethodTwo可以独立调用,因此它需要自己的注释来处理这种情况。目前我对executeUpdate为什么会导致事务提交感到困惑,尽管这可能是默认行为。 - JayPea
1
serviceDao 的事务传播是什么?它是否可能是 REQUIRES_NEW? - Hendrik
1个回答

1

当你调用方法时,你肯定是从bean工厂获取"ervice"的实例,对吧?bean工厂需要设置一个代理,在每个方法调用周围实现事务逻辑。我曾经以为这只有在"外部人员"通过代理调用方法时才起作用,并不一定在一个方法调用另一个方法时起作用,因为那个方法是在实现对象内部直接调用的,而不是通过AOP代理。


这取决于您使用的AOP方法。请参考Tomasz Nurkiewicz的链接。但是,这不能解释JayPea所描述的行为。 - Pavel Horal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接