chapter05 Spring對事務的支援
chapter05 Spring對事務的支援
一.Spring對事物支援所採用的策略
1.spring統一各種事物的程式設計方式
AOP事務的含義:
事務當作一個切面,動態地織入到目標物件,形成一個代理物件。
二、Spring的事務機制
Spring支援宣告式事務。
Spring使用事務服務代理和事務管理器(如HibernateTransactionManager)來支援事務服務。
Spring對事務的邊界多了一種巢狀事務(PROPAGATION_NESTED)。
PROPAGATION_NESTED:
如果客戶端啟動了事務T1,那麼Bean啟動一個巢狀在T1中的子事務T2;
如果客戶端沒有啟動事務,那麼
1)事物的特性:
@1,傳播行為:呼叫者如何去影響被呼叫者的事物
@2,隔離性
@3, 只讀事物
@4,超時操作
@5,回滾規則:spring容器對bean所丟擲的異常是否回滾事物
三、Spring中事務的使用
1、Spring中使用Hibernate事務
採用配置檔案的方(底層用的是用AOP的方式實現的)
Step1:配置資料來源
Step2:配置sessionfactory (同上)
Step3:配置事務管理器HibernateTransactionManager
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="mySessionFactory" />
</property>
</bean>
Step4:配置DAO
Step5:配置目標物件
Step6:配置事務代理,為相關物件注入切面,需要將目標物件,事務管理其和傳播行為傳進來,客戶端再呼叫service層物件來做事情是使用的不再是原來的service,而是這個配置了事物的代理物件
實現以上步驟的例項:
<!-- 配置資料來源 spring內建-->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/tarena</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>1234</value>
</property>
</bean>
<!-- 配置SessionFactory -->
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>entity\Account.hbm.xml</value>
<value>entity\StockAccount.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
</props>
</property>
</bean>
<!-- 配置事務管理器 -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="mySessionFactory" />
</property>
</bean>
<!-- 配置Dao -->
<bean id="abstractDAO" abstract="true">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
<bean id="accountDAO" class="dao.hibernate.AccountDAOHibernateImpl"
parent="abstractDAO" />
<bean id="stockDAO" class="dao.hibernate.StockDAOHibernateImpl"
parent="abstractDAO" />
<!-- 配置Service -->
<bean id="stockServiceTarget"
class="service.spring.StockServiceSpringImpl">
<property name="accountDAO" ref="accountDAO" />
<property name="stockDAO" ref="stockDAO" />
</bean>
<!-- 配置抽象的事務代理,用於繼承,這樣多個目標物件就可以公用一個事物管理器-->
如果不配置為抽象的。則需要在事物管理器中配置一個目標物件
<bean id="abstractService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
1)配置事務管理器
<property name="transactionManager">
<ref bean="myTransactionManager" />
</property>
2)配置事物特性
<property name="transactionAttributes">
<props>
<prop key="open*">PROPAGATION_REQUIRED,readOnly</prop>
前面一個特性配置的是事物的傳播行為,必須的
後面配置的是事物的隔離特性。不是必須的。一般不常用
<!—key配置應用事物的方法,如果是*代表所有方法都應用事物-->
<prop key="open*">PROPAGATION_REQUIRED</prop>
<prop key="buyStock">PROPAGATION_REQUIRED,-StockException</prop>
+異常型別代表提交事物,-異常型別代表回滾事物
Hirbernate對執行時異常才會回滾事物,而對檢測異常會提交事物,所以在設定異常處理規則時要注意該異常是否需要回滾事物
</props>
</property>
</bean>
<!—配置使用了事物管理器的目標物件,繼承上面的事務管理器- - >
<bean id="stockService" parent="abstractService">
3)配置目標物件
<property name="target">
<ref bean="stockServiceTarget" />
</property>
</bean>
事務屬性描述格式:
傳播行為,隔離級別,只讀事務(read-only),回滾規則
在預設情況下,Spring的容器對於非受查異常(服務模組中丟擲的非受查異常),會回滾事務。對於受查異常,會提交事務。
如果即種受查異常,也要回滾事務,可以用“- 異常型別“來宣告。同樣,對於非受查異常,如果不要求回滾事務,可以用"+異常型別"來宣告。
如何簡化事務配置?
採用標註的方式(jdk要求是1.5以上的)讓spring管理hirbernate事物
1.首先引入名稱空間
<?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.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
<!-- 配置資料來源 spring內建-->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
</bean>
<!-- 配置SessionFactory -->
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="mappingResources">
<list>
<