为什么即使在Spring服务类的第二种方法中传播= Propagation.REQUIRES_NEW时,事务也会回滚? [英] Why are the transactions rolled back even when propagation=Propagation.REQUIRES_NEW in second method in Spring service class?

查看:482
本文介绍了为什么即使在Spring服务类的第二种方法中传播= Propagation.REQUIRES_NEW时,事务也会回滚?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Basic settings are all fine now and I started to try transactions. Struts+Spring+Hibernate annotation transaction manager. This is the sample code in Action, will call a service class:

    userService.addUser();

这是 addUser()方法服务等级:

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

    }

首先,我打电话给 addUser < userDao中的/ code>,它将插入一个用户。其次,我在此服务类的另一个方法中调用 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();        
    }

这个因为空PK而失败。我想第二次调用( addUser2 )将失败但不会影响前一次调用。但是,未插入用户。

And this one will failed due to null PK. I suppose the second call (addUser2) will fail but will not affect the previous one. However, the user is not inserted.

如果我只打电话:

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

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

It is working, meaning basic settings like database is not wrong.

任何想法?

推荐答案

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

Spring's declarative transaction handling works using AOP proxies. When you get a tranasactional bean, you in fact get a proxy which wraps your bean instance, intercepts the method call, starts a transaction if necessary, then calls the actual bean's method, then commits or rollbacks the transaction if necessary.

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

But you're calling a method of your bean from another method inside the same bean, so the proxy is bypassed, and can't apply any transactional behavior.

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

Put the method in another bean, or use AspectJ, which instruments the byte code and can intercept intra-bean method calls.

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

For a more detailed explanation, see the Spring documentation.

这篇关于为什么即使在Spring服务类的第二种方法中传播= Propagation.REQUIRES_NEW时,事务也会回滚?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆