Spring顛覆了以前的編程模式,引入了IOC等全新的概念,廣受大家的喜愛。目前大多數j2ee項目都已經采用Spring框架。Spring最大的問題是太多的配置文件,使得你不僅需要維護程序代碼,還需要額外去維護相關的配置文件。最典型的就是事務配置(注:這里的“事務配置”都指“聲明式事務配置”),在Spring中進行事務配置除了定義對象自身的bean外,還需要定義一個進行事務代理的bean.如果你有n個類需要引入事務,那么你就必須定義2n個bean。維護這些bean的代價是十分昂貴的,所以必須要對事務配置進行減化。如果你是基于Spring進行架構設計,那么作為一個好的架構設計師,應該把一些公共的方面進行簡化,讓項目的開發人員只關心項目的業務邏輯,而不要花費太多的精力去關心業務邏輯之外的太多東西。所以作為一個好的架構就應該把事務管理進行簡化,讓程序員花在編程之外的工作最小化。
?
?
技術 | 事務管理器 | 內建的事務支持 |
JDBC | DataSurceTransactionManager JtaTransactionManager | JdbcTemplate和org.springframework.jdbc.object包中的所有類 |
IBATIS | DataSourceTransactionManager JtaTransactionManager | SqlMapClientTemplate和SqlClientTemplate |
Hibernate | HibernateTransactionManager JtaTransactionManager | HibernateTemplate和HibernateInterceptor |
JDO | JdoTransactionManager JtaTransactionManager | JdoTemplate和JdoInterceptor |
ApacheOJB | PersistenceBrokerTransactionManager JtaTransactionManager | PersistenceBrokerTemplate |
JMS | JmsTransactionManager | JmsTemplate |
?
?
?
?
在劃分事務時,我們需要進行事務定義,也就是配置事務的屬性。事務的屬性有傳播行業,隔離級別,超時值及只讀標志。TransactionAttribute接口指定哪些異常將導致一個回滾,哪些應該一次性提交。
?
?
?
?
?
(1)?使用ProxyFactoryBean 和TransactionInterceptor
?
?<!--定義本地數據源-->
?
?<bean id="dataSource" name="dataSource" class="org.apache.commons.dbcp.BasicDataSource"?????????? destroy-method="close">
??<property name="driverClassName" value="${jdbc.driverClassName}"/>
??<property name="url" value="${jdbc.url}"/>
??<property name="username" value="${jdbc.username}"/>
??<property name="password" value="${jdbc.password}"/>
?</bean>
?
?<!-- !定義單個jdbc數據源的事務管理器-->
?<bean id="transactionManager"?????????????? class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
??<property name="dataSource" ref="dataSource"/>
?</bean>
?
?? <!—定義攔截器-->
?<bean id="transactionInterceptor"
??? ?? class="org.springframework.transaction.interceptor.TransactionInterceptor">
??? ?<property name="transactionManager">
??? ??<ref bean="transactionManager"/>
??? ?</property>
??????? <property name="transactionAttributes">
??????????? <props>
??????????????? <prop key="insert*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="update*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="save*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????? </props>
??????? </property>
??? </bean>
?
?<!—定義業務對象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService.target"
?????? class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
??<property name="userInfoDAO"
???? ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
?? </property>
?</bean>
?
?<!—定義業務對象的事務代理對象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService" class="org.springframeword.aop.framework.ProxyFacgtoryBean">
??<property name="target"
???? ref="com.prs.application.ehld.sample.biz.service.sampleService.target">
??</property>
??<property name="interceptorNames">
???? <value>transactionInterceptor</value>
??</property>
?</bean>
?
通過ProxyFacgtoryBean和TransactionInterceptor組合使用,可以對事務進行更多的控制。所有需要事務控制的對象可以共享一個transactionInterceptor的事務屬性。
?
(2)?使用TransactionProxyFactoryBean
?
??<!—定義業務對象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService.target"
?????? class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
??<property name="userInfoDAO"
???? ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
?? </property>
?</bean>
?
??? <!—定義業務對象的事務代理對象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
????????? abstract="true">
??????? <property name="transactionManager">
??????????? <ref bean="transactionManager"/>
??????? </property>
?<property name="target"
????????? ref="com.prs.application.ehld.sample.biz.service.sampleService.target" />
??????? <property name="transactionAttributes">
??????????? <props>
??????????????? <prop key="insert*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="update*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="save*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????? </props>
??????? </property>
??? </bean>
?
使用TransactionProxyFactoryBean需要為每一個代理對象都去定義自己的事務屬性。
?
(3)?使用TransactionProxyFactoryBean及abstract屬性來簡化配置
這種方工也是目前使用得最多的一種聲明式事務配置方法
?
?
?<!--事務控制代理抽象定義 -->
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
??????? abstract="true">
??????? <property name="transactionManager">
??????????? <ref bean="transactionManager"/>
??????? </property>
??????? <property name="transactionAttributes">
??????????? <props>
??????????????? <prop key="insert*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="update*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="save*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????? </props>
??????? </property>
??? </bean>
?
??<!—定義業務對象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService.target"
?????? class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
??<property name="userInfoDAO"
???? ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
?? </property>
?</bean>
?
<!—定義業務對象的事務代理對象-->?
<bean id="com.prs.application.ehld.sample.biz.service.sampleService" parent="baseTransactionProxy">
??<property name="target"
???? ref="com.prs.application.ehld.sample.biz.service.sampleService.target">
?? </property>
?</bean>
?
使用abstract屬性,可以讓代理對象可以共享一個定義好的事務屬性,使配置簡化。
?
(4)使用BeanNameAutoProxyCreator
??? <!—定義攔截器-->
?<bean id="transactionInterceptor"
??? ?? class="org.springframework.transaction.interceptor.TransactionInterceptor">
??? ?<property name="transactionManager">
??? ??<ref bean="transactionManager"/>
??? ?</property>
??????? <property name="transactionAttributes">
??????????? <props>
??????????????? <prop key="insert*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="update*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="save*">PROPAGATION_REQUIRED</prop>
??????????????? <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????????? <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
??????????? </props>
??????? </property>
??? </bean>
?
?<!—定義bean別名自動代理創建器-->
<bean id="autoProxyCreator"
??? class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
??? <property name="interceptorNames">
??? ??? <value>transactionInterceptor</value>
??? </property>
??? <property name="beanNames">
??? ??<list>
??? ???<idref local="com.prs.application.ehld.sample.biz.service.sampleService"/>
??? ??</list>
??? </property>
?</bean>
?
??<!—定義業務對象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService"
?????? class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
??<property name="userInfoDAO"
???? ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
?? </property>
?</bean>
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?