spring聲明式事務管理方式( 基於tx和aop名字空間的xml配置+@Transactional注解)


1. 聲明式事務管理分類

聲明式事務管理也有兩種常用的方式,

一種是基於tx和aop名字空間的xml配置文件,另一種就是基於@Transactional注解。

顯然基於注解的方式更簡單易用,更清爽。

 

2. spring事務特性

spring所有的事務管理策略類都繼承自org.springframework.transaction.PlatformTransactionManager接口

其中TransactionDefinition接口定義以下特性:事務隔離級別、事務傳播行為、事務超時、事務只讀屬性、spring事務回滾規則等;

其實這些特性的介紹,網上一堆,在這我就不再啰嗦了,接下來我只想告訴你到底如何使用。

 

3. 聲明式事務管理配置兩種方式

如下都將以mybatis為例。

3.1 基於@Transactional注解的

1、首先來看一段代碼 spring.xml

<!-- MyBatis begin -->
    <!-- 1、mybatis文件配置,掃描所有mapper文件 -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 設置MyBatis核心配置文件 -->
        <property name="configLocation" value="classpath:resources/mybatis/mybatis-config.xml" />
        <!-- 設置數據源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 它表示我們的Mapper文件存放的位置,當我們的Mapper文件跟對應的Mapper接口處於同一位置的時候可以不用指定該屬性的值。 -->
        <property name="mapperLocations" value="classpath:/mappings/**/*.xml" />
        <!-- 那么在Mapper文件里面就可以直接寫對應的類名 而不用寫全路徑名了  -->
        <!-- 跟mybatis中<typeAliases>作用一樣 -->
        <!-- <property name="typeAliasesPackage" value="com.jeenotes.ssm.pojo"/> -->
    </bean>

    <!-- 2、spring與mybatis整合配置,掃描所有dao,在單數據源的情況下可以不寫sqlSessionFactoryBeanName -->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
       <!-- 設置Mapper掃描包,注意掃描的是java-dao-接口文件,不是xml -->
    <property name="basePackage" value="com.jeenotes.ssm.dao" />
    </bean>

    <!-- 3、定義事務 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    
    <!-- 4、開啟事務控制的注解支持,配置 Annotation 驅動,掃描@Transactional注解的類定義事務  -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
 <!-- MyBatis end -->

這個文件時spring和mybatis配置中的,細心的你可能會發現,這1234,4個配置之間通過id存在關聯關系的。

2、添加tx名字空間

xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:tx="http://www.springframework.org/schema/tx"  
xsi:schemaLocation="http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"

補充一下:添加到spring.xml上邊的頭部分,至於不明白xmlns,xmlns:xsi,xsi:schemaLocation等含義的同學,可以考慮看一下這篇文章了。

關於XML文檔的xmlns、xmlns:xsi和xsi:schemaLocation詳解

3、基於注解式小結

綜上,MyBatis自動參與到spring事務管理中,無需額外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的數據源與DataSourceTransactionManager引用的數據源一致即可,也就是那些id要對應起來,否則事務管理會不起作用。

 

3.2 基於tx和aop名字空間的xml配置式

同樣還是以mybatis為例,主要為aop切面配置,只看xml就可以了

注意:通常這種方式的配置我們都需要再創建一個xml文件:spring-trans.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"
> <!-- 事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 數據源 --> <property name="dataSource" ref="dataSource" /> </bean> <!-- 通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 傳播行為 --> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="create*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> <tx:method name="select*" propagation="SUPPORTS" read-only="true" /> <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice> <!-- 切面 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.jeenotes.ssm.service.*.*(..))" /> </aop:config> </beans>

4. 聲明式事務配置總結

通過上方步驟三的配置相信你已經學會如何配置聲明式事務管理了,最后總結一下:

1、首先要明確上邊的兩種方式都是聲明式事務管理的表現形式,思路千萬不要亂。

2、兩種方式配置后的使用規則

2.1、通過3.1第一種的配置,以后就可以在類、或者方法上使用@Transactional注解了(相信有的小伙伴還不知道該注解可以用在方法或者類上邊吧),

加入該注解的類或者方法,在執行過程中就會加入到同一事務中,同生共死。

通常你會看到這樣的寫法,@Transactional(readOnly = true),不得不補充一下@Transactional的屬性

屬性 類型 描述
value String 可選的限定描述符,指定使用的事務管理器
propagation enum: Propagation 可選的事務傳播行為設置
isolation enum: Isolation 可選的事務隔離級別設置
readOnly boolean 讀寫或只讀事務,默認讀寫
timeout int (in seconds granularity) 事務超時時間設置
rollbackFor Class對象數組,必須繼承自Throwable 導致事務回滾的異常類數組
rollbackForClassName 類名數組,必須繼承自Throwable 導致事務回滾的異常類名字數組
noRollbackFor Class對象數組,必須繼承自Throwable 不會導致事務回滾的異常類數組
noRollbackForClassName 類名數組,必須繼承自Throwable 不會導致事務回滾的異常類名字數組

 

2.2、通過3.2第二種的配置,會對方法名有要求,在上方的配置中舉個例子,

<tx:method name="save*" propagation="REQUIRED" />,比如如果saver中方法名是以save開頭的就會加入事務。

@Service
public class ItemCatServiceImpl implements ItemCatService {

    @Autowired
    private TbItemCatDao itemCatDao;
    
    @Override
    public void saveItemCat(EasyUITreeNode node) {
        
        itemCatDao.save(node);
        
    }
}

不知道你是否會好奇propagation屬性,該屬性里的屬性值你可以理解成@Transactional注解屬性值,如下補充一下

事務傳播行為類型

說明

REQUIRED

如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是最常見的選擇。

SUPPORTS

支持當前事務,如果當前沒有事務,就以非事務方式執行。

MANDATORY

使用當前的事務,如果當前沒有事務,就拋出異常。

REQUIRES_NEW

新建事務,如果當前存在事務,把當前事務掛起。

NOT_SUPPORTED

以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

NEVER

以非事務方式執行,如果當前存在事務,則拋出異常。

NESTED

如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類 似的操作。

3、項目中的使用選擇。

在實際項目中,這兩種方式采用哪一種實現效果都一樣,其實到底采用哪一種要看項目需求,重要的是往往並不是你去配置,所以你只需要知道有這兩種方式就行嘍。

 

本文地址:http://www.cnblogs.com/niceyoo/articles/8732891.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM