一.聲明式事務(wù)實現(xiàn)
- 將編程式事務(wù)章節(jié)中applicationContext.xml修改下:
<?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:p="http://www.springframework.org/schema/p"
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.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!-- 加載jdbc.property -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<!-- 數(shù)據(jù)源配置, 使用DBCP數(shù)據(jù)庫連接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 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}"/>
<!-- Connection Pooling Info -->
<property name="maxActive" value="3"/>
<property name="defaultAutoCommit" value="false"/>
<!-- 連接Idle一個小時后超時 -->
<property name="timeBetweenEvictionRunsMillis" value="3600000"/>
<property name="minEvictableIdleTimeMillis" value="3600000"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="abstractDao" abstract="true">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDao" class="transaction.dao.UserDaoImp" parent="abstractDao"/>
<bean id="addressDao" class="transaction.dao.AddressDaoImp" parent="abstractDao"/>
<bean id="userService" class="transaction.service.UserServiceImp">
<property name="addressService" ref="addressService"/>
<property name="userDao" ref="userDao"/>
</bean>
<bean id="addressService" class="transaction.service.AddressServiceImp">
<property name="addressDao" ref="addressDao"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="*" propagation="REQUIRED" isolation="READ_COMMITTED" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* transaction.service.*Imp.*(..))" id="serviceMethod" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>
</beans>
聲明式事務(wù)通過AOP代理方式實現(xiàn)事務(wù)管理琅坡,利用環(huán)繞通知TransactionInterceptor實現(xiàn)事務(wù)的開啟及關(guān)閉肾砂,而TransactionProxyFactoryBean內(nèi)部也是通過該環(huán)繞通知實現(xiàn)的,因此可以認(rèn)為是<tx:tags/>幫你定義了TransactionProxyFactoryBean,從而簡化事務(wù)管理
二.<tx:advice/>配置
<tx:advice id="……" transaction-manager="……">
<tx:attributes>
<tx:method name="……"
propagation=" REQUIRED"
isolation="READ_COMMITTED"
timeout="-1"
read-only="false"
no-rollback-for=""
rollback-for=""/>
……
</tx:attributes>
</tx:advice>
- <tx:advice>:id用于指定此通知的名字竞漾, transaction-manager用于指定事務(wù)管理器,默認(rèn)的事務(wù)管理器名字為“transactionManager”;
- <tx:method>:用于定義事務(wù)屬性即相關(guān)聯(lián)的方法名怖喻;
name:定義與事務(wù)屬性相關(guān)聯(lián)的方法名,將對匹配的方法應(yīng)用定義的事務(wù)屬性岁诉,可以使用“”通配符來匹配一組或所有方法锚沸,如save將匹配以save開頭的方法,而“”將匹配所有方法涕癣;
propagation:事務(wù)傳播行為定義哗蜈,默認(rèn)為“REQUIRED”,表示Required坠韩,其值可以通過TransactionDefinition的靜態(tài)傳播行為變量的“PROPAGATION_”后邊部分指定距潘,如“TransactionDefinition.PROPAGATION_REQUIRED”可以使用“REQUIRED”指定;
isolation: 事務(wù)隔離級別定義只搁;默認(rèn)為“DEFAULT”绽昼,其值可以通過TransactionDefinition的靜態(tài)隔離級別變量的“ISOLATION_”后邊部分指定,如“TransactionDefinition. ISOLATION_DEFAULT”可以使用“DEFAULT”指定:
timeout:事務(wù)超時時間設(shè)置须蜗,單位為秒硅确,默認(rèn)-1目溉,表示事務(wù)超時將依賴于底層事務(wù)系統(tǒng);
read-only:事務(wù)只讀設(shè)置菱农,默認(rèn)為false缭付,表示不是只讀;
rollback-for:需要觸發(fā)回滾的異常定義循未,以“陷猫,”分割,默認(rèn)任何RuntimeException 將導(dǎo)致事務(wù)回滾的妖,而任何Checked Exception 將不導(dǎo)致事務(wù)回滾绣檬;異常名字定義和TransactionProxyFactoryBean中含義一樣
no-rollback-for:不被觸發(fā)進(jìn)行回滾的 Exception(s);以“嫂粟,”分割娇未;異常名字定義和TransactionProxyFactoryBean中含義一樣;
三.多事務(wù)語義配置
- 明式事務(wù)配置的最佳實踐
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="merge*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="put*" propagation="REQUIRED" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="count*" propagation="SUPPORTS" read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="list*" propagation="SUPPORTS" read-only="true" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* transaction.service.*Imp.*(..))" id="serviceMethod" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>
四.@Transactional實現(xiàn)事務(wù)管理
- @Transactional配置
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED)
public void save(final User user){
userDao.save(user);
user.getAddress().setUserId(user.getId());
addressService.save(user.getAddress());
throw new RuntimeException();
}
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED,readOnly=true)
public int countAll() {
return userDao.countAll();
}
- 開啟@Transactional注解支持
<tx:annotation-driven proxy-target-class="false" transaction-manager="transactionManager" order="1"/>
Spring提供的<tx:annotation-driven/>用于開啟對注解事務(wù)管理的支持星虹,從而能識別Bean類上的@Transactional注解元數(shù)據(jù)零抬,其具有以下屬性:
transaction-manager: 指定事務(wù)管理器名字,默認(rèn)為transactionManager宽涌,當(dāng)使用其他名字時需要明確指定平夜;
proxy-target-class: 表示將使用的代碼機制,默認(rèn)false表示使用JDK代理卸亮,如果為true將使用CGLIB代理
order: 定義事務(wù)通知順序忽妒,默認(rèn)Ordered.LOWEST_PRECEDENCE,表示將順序決定權(quán)交給AOP來處理兼贸。Spring使用@Transaction來指定事務(wù)屬性段直,可以在接口、類或方法上指定寝受,如果類和方法上都指定了@Transaction,則方法上的事務(wù)屬性被優(yōu)先使用罕偎,具體屬性如下:
value: 指定事務(wù)管理器名字很澄,默認(rèn)使用<tx:annotation-driven/>指定的事務(wù)管理器,用于支持多事務(wù)管理器環(huán)境颜及;
propagation:指定事務(wù)傳播行為甩苛,默認(rèn)為Required,使用Propagation.REQUIRED指定俏站;
isolation:指定事務(wù)隔離級別讯蒲,默認(rèn)為“DEFAULT”,使用Isolation.DEFAULT指定肄扎;
readOnly:指定事務(wù)是否只讀墨林,默認(rèn)false表示事務(wù)非只讀赁酝;
timeout:指定事務(wù)超時時間,以秒為單位旭等,默認(rèn)-1表示事務(wù)超時將依賴于底層事務(wù)系統(tǒng)酌呆;
rollbackFor:指定一組異常類,遇到該類異常將回滾事務(wù)搔耕;
rollbackForClassname:指定一組異常類名字隙袁,其含義與<tx:method>中的rollback-for屬性語義完全一樣;
noRollbackFor:指定一組異常類弃榨,即使遇到該類異常也將提交事務(wù)菩收,即不回滾事務(wù);
noRollbackForClassname:指定一組異常類名字鲸睛,其含義與<tx:method>中的no-rollback-for屬性語義完全一樣娜饵;