|
Spring
的宣告式交易管理依賴於它的AOP框架來完成,使用宣告式交易管理的好處是,交易管理不侵入您所開發的組件,具體來說,您的DAO物件不會意識到正在交易
管理之中,事實上也應當如此,因為交易管理是屬於系統層面的服務,而不是業務邏輯的一部份,如果您想要改變交易管理策略的話,也只需要在定義檔中重新組態
即可。 舉個例子來說,可以將使 用 JdbcTemplate 修改一下,在不修改UserDAO類別的情況下,您可以為它加入交易管理的服務,一個簡化的方法是使用TransactionProxyFactoryBean,指定要介入的交易管理對象及其方法,這需要在定義檔案修改,如下所示:
<?xml version="1.0" encoding="UTF-8"?> TransactionProxyFactoryBean需要一個TransactionManager,由於這邊使用JDBC,所以使用 DataSourceTransactionManager,TransactionProxyFactoryBean是個代理物件,"target"屬 性指定要代理的對象,交易管理會自動介入指定的方法前後,這邊是使用"transactionAttributes"屬性指定,insert*表示指定方 法名稱 insert開頭的都要納入交易管理,您也可以指定方法全名,如果在方法執行過程中發生錯誤,則所有先前的操作自動撤回,否則正常提交。 insert*等方法上指定了"PROPAGATION_REQUIRED",表示在目前的交易中執行操作,如果交易不存在就建立一個新的,相關的常數意 義都可以在API文件中TransactionDefinition介面中找到。您可以加上多個交易定義,中間使用逗號 "," 區隔,例如您可以加上唯讀,或者是指定某個例外發生時撤回操作: PROPAGATION_REQUIRED,readOnly,-MyCheckedException
MyCheckedException前面加上"-"時,表示發生指定例外時撤消操作,如果前面加上"+",表示發生例外時立即提交。 由於userDAO被userDAOProxy代理了,所以要作的是取得userDAOProxy,而不是userDAO,例如:
package onlyfun.caterpillar; 您也可以設定不同的TransactionInterceptor來得到更多的管理細節,例如: <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://localhost:3306/demo</value> </property> <property name="username"> <value>caterpillar</value> </property> <property name="password"> <value>123456</value> </property> </bean> <bean id="transactionManager" class="org.springframework.jdbc. → datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean> <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean> <bean id="transactionInterceptor" class="org.springframework.transaction. → interceptor.TransactionInterceptor"> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributeSource"> <value> onlyfun.caterpillar.UserDAO. → insert*=PROPAGATION_REQUIRED </value> </property> </bean> <bean id="userDAOProxy" class="org.springframework.aop. → framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target"> <ref bean="userDAO"/> </property> <property name="interceptorNames"> <value>transactionInterceptor</value> </property> </bean> </beans> 即使您後來不再需要交易管理,則直接在Bean定義檔中修改配置即可,而不用修改程式進行重新編譯等動作。 宣告式交易管理是利用Spring AOP來達成,所以執行以上的程式時,請記得您的Classpath設定中必須包括spring-aop.jar。 |