Spring是SSH中的管理員,負(fù)責(zé)管理其它框架,協(xié)調(diào)各個部分的工作。今天一起學(xué)習(xí)一下Spring的事務(wù)管理。Spring配置文件中關(guān)于事務(wù)配置總是由三個組成部分,分別是DataSource、TransactionManager和代理機(jī)制這三部分,無論哪種配置方式,一般變化的只是代理機(jī)制這部分。 DataSource、TransactionManager這兩部分只是會根據(jù)數(shù)據(jù)訪問方式有所變化,比如使用Hibernate進(jìn)行數(shù)據(jù)訪問時,DataSource實際為SessionFactory,TransactionManager的實現(xiàn)為HibernateTransactionManager。 下面一起看看三種聲明式事務(wù)的具體配置:
公共配置 - <!-- 配置sessionFactory -->
- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
- <property name="configLocation">
- <value>classpath:config/hibernate.cfg.xml</value>
- </property>
- <property name="packagesToScan">
- <list>
- <value>com.entity</value>
- </list>
- </property>
- </bean>
-
- <!-- 配置事務(wù)管理器(聲明式的事務(wù)) -->
- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory"></property>
- </bean>
-
- <!-- 配置DAO -->
- <bean id="userDao" class="com.dao.UserDaoImpl">
- <property name="sessionFactory" ref="sessionFactory"></property>
- </bean>
第一種,使用tx標(biāo)簽方式 - <!-- 第一種配置事務(wù)的方式 ,tx-->
- <tx:advice id="txadvice" transaction-manager="transactionManager">
- <tx:attributes>
- <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
- <tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception" />
- <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
- <tx:method name="*" propagation="REQUIRED" read-only="true"/>
- </tx:attributes>
- </tx:advice>
-
- <aop:config>
- <aop:pointcut id="daoMethod" expression="execution(* com.dao.*.*(..))"/>
- <aop:advisor pointcut-ref="daoMethod" advice-ref="txadvice"/>
- </aop:config>
expression="execution(* com.dao.*.*(..))" 其中第一個*代表返回值,第二*代表dao下子包,第三個*代表方法名,“(..)”代表方法參數(shù)。
第二種,使用代理方式 - <!-- 第二種配置事務(wù)的方式 ,代理-->
- <bean id="transactionProxy"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
- <property name="transactionManager" ref="transactionManager"></property>
- <property name="transactionAttributes">
- <props>
- <prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
- <prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
- <prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
- <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
- </props>
- </property>
- </bean>
- <bean id="userDao" parent="transactionProxy">
- <property name="target">
- <!-- 用bean代替ref的方式-->
- <bean class="com.dao.UserDaoImpl">
- <property name="sessionFactory" ref="sessionFactory"></property>
- </bean>
- </property>
- </bean>
將transactionProxy的abstract屬性設(shè)置為"true",然后將具體的Dao的parent屬性設(shè)置為"transactionProxy",可以精簡代碼。
第三種,使用攔截器 - <!-- 第三種配置事務(wù)的方式,攔截器 (不常用)-->
- <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager" ref="transactionManager"></property>
- <property name="transactionAttributes">
- <props>
- <prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
- <prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
- <prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
- <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
- </props>
- </property>
- </bean>
- <bean id="proxyFactory" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property name="interceptorNames">
- <list>
- <value>transactionInterceptor</value>
- </list>
- </property>
- <property name="beanNames">
- <list>
- <value>*Dao</value>
- </list>
- </property>
- </bean>
Spring事務(wù)類型詳解:
PROPAGATION_REQUIRED--支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就新建一個事務(wù)。這是最常見的選擇。 PROPAGATION_SUPPORTS--支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行。 PROPAGATION_MANDATORY--支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常。 PROPAGATION_REQUIRES_NEW--新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。 PROPAGATION_NOT_SUPPORTED--以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。 PROPAGATION_NEVER--以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。 PROPAGATION_NESTED--如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則進(jìn)行與PROPAGATION_REQUIRED類似的操作。
采用注解的方式,需要注意的是,使用注解的方式需要在Spring的配置文件中加入一句話:<context:annotation-config />,其作用是開啟注解的方式。具體配置如下:
- <!--開啟注解方式-->
- <context:annotation-config />
-
- <!-- 配置sessionFactory -->
- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
- <property name="configLocation">
- <value>classpath:config/hibernate.cfg.xml</value>
- </property>
- <property name="packagesToScan">
- <list>
- <value>com.entity</value>
- </list>
- </property>
- </bean>
-
- <!-- 配置事務(wù)管理器 -->
- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory"></property>
- </bean>
-
- <!-- 第四種配置事務(wù)的方式,注解 -->
- <tx:annotation-driven transaction-manager="transactionManager"/>
注解文件:
- package com.dao;
-
- import org.springframework.orm.hibernate3.HibernateTemplate;
- import org.springframework.transaction.annotation.Propagation;
- import org.springframework.transaction.annotation.Transactional;
-
- import com.entity.User;
-
- @Transactional
- public class UserDaoImpl_BAK extends HibernateTemplate {
-
- @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
- public void addUser(User user) throws Exception {
- this.save(user);
- }
-
- @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
- public void modifyUser(User user) {
- this.update(user);
- }
-
- @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
- public void delUser(String username) {
- this.delete(this.load(User.class, username));
- }
-
- @Transactional(readOnly=true)
- public void selectUser() {
-
- }
-
- }
類頭的@Transactional為默認(rèn)事務(wù)配置,如方法沒有自己的事務(wù)類型,則按默認(rèn)事務(wù),如有自己的配置,則按自己的配置。
以上四種配置方式最常用的還是第一、二種,第三種是比較老舊的方式,而注解的方式不太適合比較大的項目,用于簡單的小項目還是很好的,其特點就是簡單明了。每種方法都有每種方法的特點跟適用的環(huán)境,沒有絕對的好與壞,只不過前兩種在實際的工作當(dāng)中用的更多一些。
好了,今天就到這里吧,看了這么長的文章,相信大家都累了,也不想再聽我在這里廢話了,哈哈。歡迎交流,歡迎拍磚。
|