zoukankan      html  css  js  c++  java
  • Spring事务注意点

    service中未带事务的方法调用了自身带事务的方法时,按下面写法数据是提交不了的。

    public String getMaxSystemVersionNo() {

            SystemVersion version = systemVersionDao.getMaxSystemVersion();

            

            version.setUpgradeDate(new Date());

            this.updateSystemVersion(version);

            return version.getVersion();

    }

    public int updateSystemVersion(SystemVersion version) {

            return systemVersionDao.updateSystemVersion(version);

    }

    原因:因为get开头的方法在spring事务配置中是不带任何事务的,所以调用自身带事务方法时也是以非事务的方式运行。如果是调用其他service中带事务方法时是可以开启事务的。

    解决方法一:

    下面写法可以使不带事务的方法变为带事务,能提交数据。

    public String getMaxSystemVersionNo() {

            SystemVersion version = systemVersionDao.getMaxSystemVersion();

           

            // 按下面这种写法取得spring bean,否则update方不能启事务

            version.setUpgradeDate(new Date());

    SystemVersionService service = (SystemVersionService) ApplicationContextHolder.getApplicationContext().getBean(

                    "systemVersionService");

    service.updateSystemVersion(version);

           

            return version.getVersion();

    }

    解决方法二:

    使该service实现 BeanSelfAware 接口类,并在该类中添加自身serivce属性, 如下写法可以使不带事务的方法变为带事务,能提交数据。具体参考类FundsAlipayServiceImpl.java中的写法。

    public class SystemVersionServiceImpl implements SystemVersionService, BeanSelfAware {

    private SystemVersionService selfBean;

        @Cacheable(id = "getMaxSystemVersionNo")

        public String getMaxSystemVersionNo() {

            SystemVersion version = systemVersionDao.getMaxSystemVersion();

           

            // 按下面这种写法取得spring bean,否则update方不能启事务

            version.setUpgradeDate(new Date());

            selfBean.updateSystemVersion(version);

            return version.getVersion();

        }

        @Override

        public void setSelf(Object proxyBean) {

            this.selfBean = (SystemVersionService) proxyBean;

        }

    }

    注:该写法在tddl读写分离时写操作有可能发布到从库上。

    已解决,原因如下:

    selfBean.updateSystemVersion(version)方法没有走AOP切面,从而导致没有启用事务,而tddl是通过事务判断走主库还是从库的,没有启用事务所以就走从库了。

    selfBean方法没有走AOP切面的原因是service相互依赖调用引起的,详见下面帖子:

    Spring事务处理时自我调用的解决方案及一些实现方式的风险

    http://www.iteye.com/topic/1122740

  • 相关阅读:
    Lua脚本语法说明(修订)
    C++ 程序文档生成器介绍(doxygen)
    [转]最快速度找到内存泄漏
    MyEclipse 8.5下安装tomcat插件
    Linux解压rar文件(unrar安装和使用,分卷解压)
    禁止root用户远程登录或者禁止其他用户登录而不删除它
    linux配置IP的方法
    log4j xml配置详解
    Sqlldr使用介绍
    Linux查看CPU和内存使用情况
  • 原文地址:https://www.cnblogs.com/wangliyue/p/6214129.html
Copyright © 2011-2022 走看看