事务采用的是注解方式。
持久层用的是MyBatis,简单配置如下:
id="mysqlDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> value="dataSource"/> name="url" value="${mysql.database.url}"/> name="username" value="${mysql.database.user}"/> name="password" value="${mysql.database.password}"/> name="initialSize" value="5"/> name="minIdle" value="${mysql.database.minIdle}"/> name="maxActive" value="${mysql.database.maxActive}"/> name="maxWait" value="60000"/> name="timeBetweenEvictionRunsMillis" value="60000"/> name="minEvictableIdleTimeMillis" value="300000"/> name="validationQuery" value="SELECT 1 FROM DUAL" /> name="testWhileIdle" value="true"/> name="testOnBorrow" value="false"/> name="testOnReturn" value="false"/> name="filters" value="stat"/>
id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> name="dataSource" ref="mysqlDataSource"/> name="typeAliasesPackage" value="com.xxxxx.model"/> name="configLocation" value="classpath:/conf/mybatis/mybatis-config.xml"/> name="mapperLocations">
classpath:/mappers/*.xml class="org.mybatis.spring.mapper.MapperScannerConfigurer"> name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> name="basePackage" value="com.xxxxx.dao"/>
id="txMysqlManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <tx:annotation-driven transaction-manager="txMysqlManager" proxy-target-class="true" order="50"/>name="dataSource" ref="mysqlDataSource" />
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) ; //数据库上是3 trainingMapper.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方法。