使用spring事务管理的几个注意事项
2017-05-15 00:00
316 查看
#正确的配置方案
基本上涉及到spring事务管理的文章都会交待通过“配置+注解”的方式实现目标。首先在xml配置文件中添加以下配置:
然后在需要启动事务管理的方法处添加
例如上例的代码就会因为异常回滚,保持方法的原子性操作。
但是,会有以下几个情况,可能会导致事务不起作用。
#问题排查
实际上spring提供的对数据库操作的事物管理特性是基于jdbc的,而jdbc事务的使用方法为:
获取连接 Connection con = DriverManager.getConnection()
开启事务con.setAutoCommit(true/false);
执行CRUD
提交事务/回滚事务 con.commit() / con.rollback();
关闭连接 conn.close();
可如果我们使用spring的事务管理功能,就可以通过简单的一个
spring的事务管理功能是通过创建aop代理来实现的,所以最直接查找问题的方法就是看你调用的对象有没有被封装成aop代理。
如果你发现你所使用的对象不是aop对象,那么就要挨个排查具体原因了。
#问题原因&解决方案
##多个配置文件重复扫描
最常见的spring-mvc项目一般会包含两个配置文件:
让带了
##public方法
我们为之添加
##数据库引擎
必须使用
基本上涉及到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事务的使用方法为:
获取连接 Connection con = DriverManager.getConnection()
开启事务con.setAutoCommit(true/false);
执行CRUD
提交事务/回滚事务 con.commit() / con.rollback();
关闭连接 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.xml和
spring-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是不行的。
相关文章推荐
- 使用dedecms建站的几个注意事项
- Windows Phone - 使用Sterling数据库几个注意事项『转』
- JavaScript服务器端开发(函数实参对象arguments使用的几个注意事项)
- 使用rem的几个注意事项
- lucene.net 使用过程中的 几个注意事项(含termquery 和QueryParser 的区别)
- Windows Phone - 使用Sterling数据库几个注意事项
- Oracle sqlldr使用的几个注意事项
- windows下使用postgresql8.01的几个注意事项
- JAVA equals Douible BigDecimal 使用时候的几个注意事项
- ireport使用时的几个注意事项
- 索引的使用要注意几个事项
- PHP使用静态方法的几个注意事项
- gsoap-2.8使用时需要注意的几个事项
- Android使用套接字的几个注意事项
- libcurl 使用的几个注意事项
- mysq l索引使用的几个注意事项
- ASP.NET MVC 使用MSBuild部署的几个注意事项
- 使用Exchange 2007的几个注意事项
- libcurl 使用的几个注意事项
- 在使用分组操作时的几个注意事项