为什么即使在Spring服务类的第二种方法中传播= Propagation.REQUIRES_NEW时,事务也会回滚?

Ask*_*ska 5 java spring dao hibernate transactionmanager

基本设置现在都很好,我开始尝试交易.Struts + Spring + Hibernate注释事务管理器.这是Action中的示例代码,将调用服务类:

    userService.addUser();
Run Code Online (Sandbox Code Playgroud)

这是addUser()服务类中的方法:

    @Transactional(value="deu"  )
    public void addUser() {     
        userDao.addUser();
        this.addUser2();

    }
Run Code Online (Sandbox Code Playgroud)

首先,我调用addUser了userDao,它将插入一个用户.其次,我addUser2在这个服务类中调用了另一个方法.

    @Transactional(value="deu" , propagation=Propagation.REQUIRES_NEW  )
    public void addUser2()   {      
    //should be a new transaction and will not affect the previous one. 
            //this one will fail but should not affect the previous one.
        userDao.addUserFail();        
    }
Run Code Online (Sandbox Code Playgroud)

由于无效PK,这一次将失败.我想第二个call(addUser2)会失败,但不会影响前一个.但是,未插入用户.

如果我只打电话:

   @Transactional(value="deu"  )
    public void addUser() {     
        userDao.addUser();
        //this.addUser2();      
    }
Run Code Online (Sandbox Code Playgroud)

它正在工作,这意味着像数据库这样的基本设置没有错.

任何的想法?

JB *_*zet 7

Spring的声明式事务处理使用AOP代理.当你得到一个tranasactional bean时,你实际上得到一个包装你的bean实例的代理,拦截方法调用,必要时启动一个事务,然后调用实际bean的方法,然后在必要时提交或回滚事务.

但是你从同一个bean中的另一个方法调用bean的方法,因此代理被绕过,并且不能应用任何事务行为.

将该方法放在另一个bean中,或者使用AspectJ,它可以检测字节代码并拦截bean内方法调用.

有关更详细的说明,请参阅Spring文档.