简介:事物的注解我们可以注解在类上也可以注解在方法上。默认事物的注解@Transactional(propagation=Propagation.REQUIRED,rollbackFor = {RuntimeException.class},timeout=30)这是默认的事物即你在类或者方法上注解@Transactional后默认会是上面的注解
propagation =Propagation.REQUIRED //默认事物传播行为
rollbackFor={RuntimeException.class}// 设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。
一、首先保证你的配置事物的配置文件正确,我们的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd" default-lazy-init="true"><description>Spring公共配置</description>
<!-- MyBatis配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --> <property name="typeAliasesPackage" value="com.asiainfo.tfsPlatform.po" /> <!-- 显式指定Mapper文件位置 --> <property name="mapperLocations" value="classpath*:/mapper/**/*Mapper.xml" /> </bean> <!-- 扫描basePackage下所有以@MyBatisRepository标识的 接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.asiainfo.tfsPlatform.mapper.**" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> <!-- <property name="annotationClass" value="com.asiainfo.tfsPlatform.repository.mybatis.MyBatisRepository"/> --> </bean> <!-- 开启事务注解驱动 --> <tx:annotation-driven /> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> <!-- 定义aspectj --> <aop:aspectj-autoproxy proxy-target-class="true"/><!-- production环境 -->
<beans profile="production"> <context:property-placeholder ignore-resource-not-found="true" location="classpath*:/application-mybatis.properties" /><!-- 数据源配置,使用应用内的Tomcat JDBC连接池 -->
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <!-- Connection Info --> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxActive" value="${jdbc.pool.maxActive}" /> <property name="maxIdle" value="${jdbc.pool.maxIdle}" /> <property name="minIdle" value="0" /> <property name="defaultAutoCommit" value="false" /> <!-- 连接Idle10分钟后超时,每1分钟检查一次 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <property name="minEvictableIdleTimeMillis" value="600000" /> </bean> </beans> <!-- local development环境 --> <beans profile="development"> <context:property-placeholder ignore-resource-not-found="true" location="classpath*:/application-mybatis.properties, classpath*:/application-mybatis.development.properties" /><!-- Tomcat JDBC连接池 -->
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="defaultAutoCommit" value="false" /> </bean> </beans><!-- functional test环境 -->
<beans profile="functional"> <context:property-placeholder ignore-resource-not-found="true" location="classpath*:/application-mybatis.properties, classpath*:/application.functional.properties, classpath*:/application.functional-local.properties" /> <!-- Tomcat JDBC连接池 --> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="defaultAutoCommit" value="false" /> </bean> </beans> <!-- unit test环境 --> <beans profile="test"> <context:property-placeholder ignore-resource-not-found="true" location="classpath*:/application-mybatis.properties, classpath*:/application.test.properties" /> <!-- Spring Simple连接池 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> <property name="driverClass" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> </beans> </beans>二、如果配置文件对了,类或者方法上注解了@Transaction 但是注解事物还是不起作用,批量提交后,不回滚,
解决方法一:不要对方法进行try{}catch(Exception e){}操作
解决方法二:如果对方法进行try{}catch(Exception e){ throw new RuntimeException("运行时出错!")} 一定要抛出运行异常。
三、下面是我功能测试代码:
/** * 功能描述:汇总清单表数据到sp_stat_other表中 * pankx * @date 2016年5月13日 上午10:48:42 * @param * @return void */ @Transactional(propagation=Propagation.REQUIRED,rollbackFor = {RuntimeException.class, Exception.class}) public boolean sumDataToSpstatother(String month) { //获取清单表汇总数据 List<Map<String,Object>> spdata = null; try{ spdata =countRecordByMonth(month); SpStatOther spStatOther =null; // int i=0; if(spdata!=null && spdata.size()>0){ for(Map<String,Object> data:spdata){ spStatOther = new SpStatOther(); /* if(i==2){ 注释是测试事物的 spStatOther.setMonth(month); spStatOther.setPartyId(data.get("PARTY_ID").toString()); //spStatOther.setSvcCode(SVC_CODE); spStatOther.setSpServiceId(Long.valueOf(data.get("SP_SERVICE_ID").toString())); spStatOther.setCallNum(Long.valueOf(data.get("CALL_NUM").toString())); spStatOther.setDealDate(new Date()); spStatOtherMapper.insertSelective(spStatOther); }else{*/ spStatOther.setMonth(month); spStatOther.setPartyId(data.get("PARTY_ID").toString()); spStatOther.setSvcCode(SVC_CODE); spStatOther.setSpServiceId(Long.valueOf(data.get("SP_SERVICE_ID").toString())); spStatOther.setCallNum(Long.valueOf(data.get("CALL_NUM").toString())); spStatOther.setDealDate(new Date()); spStatOtherMapper.insertSelective(spStatOther);/*}
i++;*/ } } logger.info("[汇总] 数据汇总成功"); return true; }catch(Exception e){ e.printStackTrace(); logger.info("[汇总] 数据汇总失败" ); throw new RuntimeException("运行时出错!"); } }四、以下是spring配置事物要注意的
注意的几点:
1 @Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能. 2用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚.默认遇到运行期例外(throw new RuntimeException("注释");)会回滚,即遇到不受检查(unchecked)的例外时回滚;而遇到需要捕获的例外(throw new Exception("注释");)不会回滚,即遇到受检查的例外(就是非运行时抛出的异常,编译器会检查到的异常叫受检查例外或说受检查异常)时,需我们指定方式来让事务回滚要想所有异常都回滚,要加上 @Transactional( rollbackFor={Exception.class,其它异常}) .如果让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class) 如下: @Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚 public void methodName() { throw new Exception("注释"); } @Transactional(noRollbackFor=Exception.class)//指定不回滚,遇到运行期例外(throw new Runt希望对大家有帮助!