spring註解性的事物@Transactional不起做用

簡介:事物的註解咱們能夠註解在類上也能夠註解在方法上。默認事物的註解@Transactional(propagation=Propagation.REQUIRED,rollbackFor = {RuntimeException.class},timeout=30)這是默認的事物即你在類或者方法上註解@Transactional後默認會是上面的註解spring

propagation =Propagation.REQUIRED //默認事物傳播行爲sql

rollbackFor={RuntimeException.class}// 設置須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,則進行事務回滾。數據庫

1、首先保證你的配置事物的配置文件正確,咱們的配置文件以下:apache

<?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"/>tomcat

    <!-- production環境 -->
    <beans profile="production">
        <context:property-placeholder ignore-resource-not-found="true"
            location="classpath*:/application-mybatis.properties" />    mybatis

        <!-- 數據源配置,使用應用內的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" />    app

        <!-- 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>url

2、若是配置文件對了,類或者方法上註解了@Transaction 可是註解事物仍是不起做用,批量提交後,不回滾,

解決方法一:不要對方法進行try{}catch(Exception e){}操做

解決方法二:若是對方法進行try{}catch(Exception e){    throw new RuntimeException("運行時出錯!")} 必定要拋出運行異常。

3、下面是我功能測試代碼:


    /**
     * 功能描述:彙總清單表數據到sp_stat_other表中
     * @author 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("運行時出錯!");
        }
    }

4、如下是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                

但願對你們有幫助!

相關文章
相關標籤/搜索