spring 事务注意事项 -- 事务注解一定写到service最外层
2016-08-10 16:57
447 查看
事务采用的是注解方式。持久层用的是MyBatis,简单配置如下:
<!--数据源配置, 使用 Druid 数据库连接池--> <bean id="mysqlDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <qualifier value="dataSource"/> <!-- 基本属性 url、user、password --> <property name="url" value="${mysql.database.url}"/> <property name="username" value="${mysql.database.user}"/> <property name="password" value="${mysql.database.password}"/> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="5"/> <property name="minIdle" value="${mysql.database.minIdle}"/> <property name="maxActive" value="${mysql.database.maxActive}"/> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="60000"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000"/> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="300000"/> <property name="validationQuery" value="SELECT 1 FROM DUAL" /> <property name="testWhileIdle" value="true"/> <property name="testOnBorrow" value="false"/> <property name="testOnReturn" value="false"/> <!-- 配置监控统计拦截的filters --> <property name="filters" value="stat"/> </bean>
<!-- mybatis文件配置,扫描所有mapper文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="mysqlDataSource"/> <property name="typeAliasesPackage" value="com.xxxxx.model"/> <property name="configLocation" value="classpath:/conf/mybatis/mybatis-config.xml"/> <!-- 自动扫描映射文件 --> <property name="mapperLocations"> <list> <value>classpath:/mappers/*.xml</value> </list> </property> </bean> <!-- spring与mybatis整合配置,扫描所有dao --> <!-- 扫描basePackage下所有以@MyBatisRepository注解的接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <property name="basePackage" value="com.xxxxx.dao"/> </bean>
<!-- mysqlServer事务,注意 使用此事务时需要显示写明Transaction(value="txMysqlManager")--> <bean id="txMysqlManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="mysqlDataSource" /> </bean> <!-- 事务控制 --> <!-- mysqlServer事务,注意 使用此事务时需要显示写明Transaction(value="txMysqlManager")--> <tx:annotation-driven transaction-manager="txMysqlManager" proxy-target-class="true" order="50"/>controller代码如下:
@RequestMapping(value="/testTransaction", method={RequestMethod.GET, RequestMethod.POST}) public void testTransaction() { try { ybsTrainingService.commitTransactionBase(); } catch (Exception e) { logger.info("测试内容失败", e); } }servce代码如下:
@Transactional(value = "txMysqlManager", rollbackFor = Exception.class) public void commitTransactionBase() { commitTransaction(); } private void commitTransaction() { TrainingState trainingState = new TrainingState();
trainingState.setTrainingId(220);trainingState.setTrainingState(1); //数据库上是3trainingMapper.updateTrainingState(ybsTrainingState);CourseState ybsCourseState = new CourseState();courseState.setCourseState(1); //数据库上是2 courseState.setId(9348172);courseMapper.updateCourseState(ybsCourseState); //如下两行是异常测试 ,会报空指针异常
ybsCourseState = null; ybsCourseState.setCourseState(1); }注意:如果将 “@Transactional(value ="txMysqlManager", rollbackFor = Exception.class)” 放到子方法commitTransaction()上边,如下,则事务不会起作用。
public void commitTransactionBase() { commitTransaction(); }
@Transactional(value = "txMysqlManager", rollbackFor = Exception.class) private void commitTransaction() {
TrainingState trainingState = new TrainingState();
trainingState.setTrainingId(220);trainingState.setTrainingState(1); //数据库上是3
trainingMapper.updateTrainingState(ybsTrainingState);
CourseState ybsCourseState = new CourseState();
courseState.setCourseState(1); //数据库上是2
courseState.setId(9348172);
courseMapper.updateCourseState(ybsCourseState);
//如下两行是异常测试 ,会报空指针异常
ybsCourseState = null;ybsCourseState.setCourseState(1);}补充,最外层service方法,在这里边是commitTransactionBase() 方法,就是被controller直接调用的。所以肯定是public 修饰,如果是私有private修饰 ,则事务也不会生效,当然正常情况下,controller也不会调用到其他类的private方法。
相关文章推荐
- 敏捷开发之Scrum扫盲篇
- Java SWT 文本框 垂直 居中
- 深入理解Java:SimpleDateFormat安全的时间格式化
- Spring+Netty+Protostuff+ZooKeeper实现轻量级RPC服务
- JDK自带的native2ascii工具介绍
- spring jar包详解
- 转载:java程序打包成jar 配置文件信息路径
- java利用zxing编码解码一维码与二维码
- java(高级)特性
- 学习JDK与CGLib两种动态代理机制
- 华为OJ——坐标移动
- Java File的mkdir()和mkdirs()使用区别
- java之序列化与反序列化
- Java概述
- Java HashSet详解
- Java泛型-类型擦除
- 一起读guavaCache源码
- java中关于ArrayList,LinkedList,HashSet,Vector,TreeSet的区别和使用
- JAVA成员变量和静态变量的区别
- Java集合容器优化