spring事務(wù)管理
zhuanzaizi:z_xiaofei168
6.1、spring的事務(wù)管理器
Spring框架并沒有直接管理用戶的應(yīng)用系統(tǒng)中的事務(wù),它只是提供許多供用戶選擇的事務(wù)管理器,然后將事務(wù)管理的責(zé)任委托給與此事務(wù)管理器對(duì)應(yīng)的持久化技術(shù)的事務(wù)實(shí)現(xiàn)。
事務(wù)管理實(shí)現(xiàn) |
使用時(shí)機(jī) |
org.springframework.jdbc.datasource. DataSourceTransactionManager |
在單一的JDBC DataSource中管理事務(wù) |
org.springframework.orm.hibernate3. HibernateTransactionManager |
當(dāng)持久化機(jī)制是Hibernate時(shí),用它來管理職務(wù) |
org.springframework.orm. jpa.JpaTransactionManager |
當(dāng)JPA用作持久化時(shí),用它來管理職務(wù) |
org.springframework.transaction. jta.JtaTransactionManager |
使用一個(gè)JTA實(shí)現(xiàn)來管理事務(wù)。在一個(gè)事務(wù)跨越多個(gè)資源時(shí)必須使用 |
配置文件中的配置如下:
<bean id=”transactionManager” class=” org.springframework.jdbc.datasource. DataSourceTransactionManager”>
<property name=”dataSource” ref=” dataSource”/>
</bean>
6.2、事務(wù)屬性介紹
1>.傳播行為
傳播行為 |
說明 |
PROPAGATION_REQUIRED |
必須在一個(gè)事務(wù)中執(zhí)行。如果當(dāng)前有一個(gè)事務(wù)正在進(jìn)行,該方法將會(huì)在那個(gè)事務(wù)中執(zhí)行。否則要開始一個(gè)新事務(wù)。Spring事務(wù)傳播行為的默認(rèn)值。 |
PROPAGATION_SUPPORTS |
支持現(xiàn)有的事務(wù)。如果當(dāng)前沒有事務(wù)在進(jìn)行,就以非事務(wù)的方式執(zhí)行 |
PROPAGATION_MANDATORY |
方法必須在一個(gè)現(xiàn)有事務(wù)中進(jìn)行,否則會(huì)拋出異常。 |
PROPAGATION_REQUIRES_NEW |
必須在它自己的新啟事務(wù)里進(jìn)行。如果現(xiàn)有事務(wù)在進(jìn)行就先暫停它 |
PROPAGATION_NOT_SUPPORTED |
不應(yīng)在事務(wù)中進(jìn)行。如果現(xiàn)有事務(wù)在進(jìn)行就先暫停它 |
PROPAGATION_NEVER |
不應(yīng)在事務(wù)中進(jìn)行。如果現(xiàn)有事務(wù)在進(jìn)行就拋出異常 |
PROPAGATION_NESTED |
如果現(xiàn)有事務(wù)正在進(jìn)行,則該方法運(yùn)行在一個(gè)嵌套式事務(wù)中。否則PROPAGATION_REQUIRED執(zhí)行 |
2>.隔離級(jí)別
隔離級(jí)別 |
說明 |
ISOLATION_DEFAULT |
使用底層數(shù)據(jù)庫默認(rèn)的隔離級(jí)別spring事務(wù)隔離級(jí)別的默認(rèn)值 |
ISOLATION_READ_UNCOMMITED |
充許另一個(gè)事務(wù)可以讀到這個(gè)事務(wù)未提交的數(shù)據(jù)可能導(dǎo)致臟讀、不可重復(fù)讀和幻讀。 |
ISOLATION_READ_COMMITED |
保證一個(gè)事務(wù)修改的數(shù)據(jù)提交后才能被另一個(gè)事務(wù)讀取可能導(dǎo)致不可重復(fù)讀和幻讀。 |
ISOLATION_REPEATABLE_READ |
要求對(duì)相同字段的多次讀取的結(jié)果必須相同,除非事務(wù)本身更新了數(shù)據(jù)可能導(dǎo)致幻讀。 |
ISOLATION_SERIALIZABLE |
事務(wù)被處理為順序執(zhí)行可以防止臟讀、不可重復(fù)讀、幻讀。 |
3>.只讀提示
如果事務(wù)只對(duì)后端數(shù)據(jù)進(jìn)行讀操作,則后端數(shù)據(jù)庫可以采用一些優(yōu)化措施來提高執(zhí)行效率。但必須在事務(wù)中才有效。也就是說要搭配傳播行為PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED 來設(shè)置。
4>.事務(wù)超時(shí)間隔
還可以設(shè)置事務(wù)的超時(shí)間隔,讓事務(wù)在特定秒數(shù)后自動(dòng)回滾,不必等它自己結(jié)束。由于計(jì)時(shí)是從事事務(wù)開始時(shí)算起的,所以它也得搭配傳播行為為 PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED 來設(shè)置。
5>.回滾規(guī)則
當(dāng)事務(wù)運(yùn)行過程中拋出異常時(shí),事務(wù)可以被聲明為回滾或者不回滾。默認(rèn)情況下只在出現(xiàn)RuntimeExceptio才會(huì)回滾,而在出現(xiàn)受檢異常時(shí)不回滾。
當(dāng)然,也可以改變這種回滾規(guī)則,可以聲明一個(gè)事務(wù)在出現(xiàn)特定的受檢異常時(shí)能回滾。也可以聲明一個(gè)事務(wù)在出現(xiàn)特定的非受檢異常時(shí)不回滾。
6.3、聲明式事務(wù)管理
1>.基于xml配置方式
第1步:定義事務(wù)通知
第2部:把事務(wù)通知綁定到切入點(diǎn)
- <?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:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
- <!-- 配置不帶連接池的數(shù)據(jù)源 -->
- <bean id="dataSource"
- class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="com.mysql.jdbc.Driver" />
- <property name="url" value="jdbc:mysql:///spring" />
- <property name="username" value="root" />
- <property name="password" value="123" />
- </bean>
- <!-- JDBC事務(wù)管理器 -->
- <bean id="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <!-- DataSource事務(wù)管理器需要數(shù)據(jù)源實(shí)例 -->
- <property name="dataSource" ref="dataSource"/>
- </bean>
- <!-- 第1步:定義事務(wù)通知(主要是針對(duì)指定事務(wù)管理器對(duì)應(yīng)的事務(wù)實(shí)現(xiàn)配置事務(wù)參數(shù)) -->
- <tx:advice id="txAdvice" transaction-manager="transactionManager">
- <tx:attributes>
- <!-- 對(duì)選定的方法配置詳細(xì)的事務(wù)屬性 -->
- <tx:method name="find*" read-only="true" />
- <tx:method name="*"/>
- </tx:attributes>
- </tx:advice>
- <!-- 第2步:AOP配置 -->
- <aop:config>
- <!-- 聲明事務(wù)切入點(diǎn)(配置哪些類的哪些方法參與事務(wù)) -->
- <aop:pointcut id="AllServiceMethod"
- expression="execution(* com.zxf.service.*.*(..))" />
- <!-- 通知器(把事務(wù)通知綁定到切入點(diǎn)) -->
- <aop:advisor pointcut-ref="AllServiceMethod" advice-ref="txAdvice" />
- </aop:config>
- <!-- 以下是Spring容器管理的Bean -->
- <bean id="accountDao" class="com.zxf.dao.AccountDaoJDBCImpl">
- <property name="dataSource" ref="dataSource" />
- </bean>
- <bean id="accountService" class="com.zxf.service.AccountService">
- <property name="accountDao" ref="accountDao"/>
- </bean>
- <!-- Hibernate事務(wù)管理器
- <bean id="txManager2"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref ="sessionFactory"/>
- </bean>
- -->
- <!-- JPA事務(wù)管理器
- <bean id="txManager3"
- class="org.springframework.orm.jpa.JpaTransactionManager">
- <property name="entityManagerFactory" ref ="entityManagerFactory"/>
- </bean>
- -->
- </beans>
2>.基于注解方式
第1步:在spring配置文件中啟用對(duì)AspectJ注解的支持
- <?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:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
- <!-- 配置不帶連接池的數(shù)據(jù)源 -->
- <bean id="dataSource"
- class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="com.mysql.jdbc.Driver" />
- <property name="url" value="jdbc:mysql:///spring_04" />
- <property name="username" value="root" />
- <property name="password" value="root" />
- </bean>
- <!-- JDBC事務(wù)管理器 -->
- <bean id="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <!-- DataSource事務(wù)管理器需要數(shù)據(jù)源實(shí)例 -->
- <property name="dataSource" ref="dataSource"/>
- </bean>
- <!-- 啟用對(duì)事務(wù)注解的支持 -->
- <tx:annotation-driven transaction-manager="transactionManager"/>
- <!-- 以下是Spring容器管理的Bean -->
- <bean id="accountDao" class="com.zxf.dao.AccountDaoJDBCImpl">
- <property name="dataSource" ref="dataSource" />
- </bean>
- <bean id="accountServiceByTxAnnotation"
- class="com.zxf.service.AccountServiceByTxAnnotation">
- <property name="accountDao" ref="accountDao"/>
- </bean>
- </beans>
第2步:用@Transactional注解指定接口、類或方法的事務(wù)屬性
- package com.zxf.service;
- import java.util.List;
- import org.springframework.transaction.annotation.Transactional;
- import com.zxf.dao.AccountDao;
- import com.zxf.domain.Account;
- /** Account業(yè)務(wù)邏輯類--基于注解方式的聲明式事務(wù)管理配置 */
- @Transactional //指定需要聲明式事務(wù),事務(wù)屬性使用默認(rèn)值
- public class AccountServiceByTxAnnotation {
- private AccountDao accountDao;
- public void setAccountDao(AccountDao accountDao){
- this.accountDao = accountDao;
- }
- }