使用spring事务管理的几个注意事项

#正确的配置方案 基本上涉及到spring事务管理的文章都会交待通过“配置+注解”的方式实现目标。首先在xml配置文件中添加以下配置:

    <!-- 定义事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="adminDataSource" />
    </bean>
    <!-- 使用annotation注解方式配置事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"  />

然后在需要启动事务管理的方法处添加@Transactional注解:

    /*这里我是在service中直接调用jdbc操作的,所以把service中的方法加上@Transactional注解*/
    @Transactional
    public void invoke() {
        OaTag tag = new OaTag();
        oaTagMapper.insert(tag);
        throw new RuntimeException();
    }

例如上例的代码就会因为异常回滚,保持方法的原子性操作。

但是,会有以下几个情况,可能会导致事务不起作用。 #问题排查 实际上spring提供的对数据库操作的事物管理特性是基于jdbc的,而jdbc事务的使用方法为:

  1. 获取连接 Connection con = DriverManager.getConnection()
  2. 开启事务con.setAutoCommit(true/false);
  3. 执行CRUD
  4. 提交事务/回滚事务 con.commit() / con.rollback();
  5. 关闭连接 conn.close(); 可如果我们使用spring的事务管理功能,就可以通过简单的一个@Transactional注解实现对整个方法的事务控制。

spring的事务管理功能是通过创建aop代理来实现的,所以最直接查找问题的方法就是看你调用的对象有没有被封装成aop代理。

    /*在controller中判断调用的service对象实例是否为aop代理*/
    @RequestMapping("invoke")
    public void invoke(){
        LOG.info("isAopProxy:{}", AopUtils.isAopProxy(platService)); #判断是否为面向切面代理,一般理解为aop即CGLIB代理的特性
        LOG.info("isCglibProxy:{}", AopUtils.isCglibProxy(platService)); #直接判断是否为CGLIB代理
        LOG.info("isJDKDynamicProxy:{}", AopUtils.isJdkDynamicProxy(platService)); #判断是否为JDK动态代理,我们不希望它是这种代理
        platService.invoke();
    }

如果你发现你所使用的对象不是aop对象,那么就要挨个排查具体原因了。

#问题原因&解决方案 ##多个配置文件重复扫描 最常见的spring-mvc项目一般会包含两个配置文件:application-context.xmlspring-mvc.xml 可能在你的项目中他们有不一样的名字,但是实际上我们通过两个文件所实现的目标是一样的。通过前者来配置context,是整个项目的大环境配置文件;后者用来配置spring-mvc DispatcherServlet,它负责的是对servlet的定义。有的时候我们会混淆两者的作用,比如当你把<context:component-scan>标签放在两个文件,就有可能让后调用spring-mvc.xml的servlet创建的service-bean,覆盖application-context.xml中定义的bean。所以我们需要通过在spring-mvc.xml 中 添加:

<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>

让带了@Service标签的bean不会被spring-mvc.xml覆盖。 ##public方法 我们为之添加@Transactional注解的方法必须是被controller直接调用的public方法。比如下面这样的调用是不可用的:

    /*service*/
    public void invoke() {
        i();
    }

    @Transactional
    private void i(){ #pri
        OaTag tag = new OaTag();
        tag.setPlatId(12);
        tag.setTag("测试tag");
        oaTagMapper.insert(tag);
        throw new RuntimeException();
    }

##数据库引擎 必须使用InnoDB这样的事务型数据库引擎,比如MyISAM是不行的。

转载于:https://my.oschina.net/djzhu/blog/900544

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值