1. 程式人生 > >chapter05 Spring對事務的支援

chapter05 Spring對事務的支援

chapter05 Spring對事務的支援

一.Spring對事物支援所採用的策略

1.spring統一各種事物的程式設計方式

AOP事務的含義:

事務當作一個切面,動態地織入到目標物件,形成一個代理物件。

二、Spring的事務機制

Spring支援宣告式事務。

Spring使用事務服務代理和事務管理器(如HibernateTransactionManager)來支援事務服務。

Spring對事務的邊界多了一種巢狀事務(PROPAGATION_NESTED)。

PROPAGATION_NESTED

如果客戶端啟動了事務T1,那麼Bean啟動一個巢狀在T1中的子事務T2

如果客戶端沒有啟動事務,那麼

Bean會啟動一個新的事務,類似於REQUIRED_NEW

1)事物的特性:

@1,傳播行為:呼叫者如何去影響被呼叫者的事物

@2,隔離性

@3, 只讀事物

@4,超時操作

@5,回滾規則:spring容器對bean所丟擲的異常是否回滾事物

三、Spring中事務的使用

1Spring中使用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>

<