Spring框架引人註目的重要因素之一是它全面的事務支持。Spring框架提供瞭一致的事務管理抽象,這帶來瞭以下好處:
1:為復雜的事務API提供瞭一致的編程模型,如JTA、JDBC、Hibernate、JPA和JDO
2:支持聲明式事務管理
3:提供比復雜的事務API(諸如JTA)更簡單的、更易於使用的編程式事務管理API
4:非常好地整合Spring的各種數據訪問抽象
Spring事務抽象的關鍵是事務策略的概念。這個概念由org.springframework.transaction.PlatformTransactionManager接口定義:
java代碼:
查看復制到剪貼板打印
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition)
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
ge
tTransaction(..)方法根據一個類型為 TransactionDefinition 的參數返回一個 TransactionStatus 對象。返回的 TransactionStatus 對象可能代表一個新的或已經存在的事務(如果在當前調用堆棧有一個符合條件的事務。如同J2EE事務環境,一個 TransactionStatus 也是和執行 線程 綁定的)
TransactionDefinition接口指定
1:事務隔離:當前事務和其它事務的隔離的程度。例如,這個事務能否看到其他事務未提交的寫數據?
2:事務傳播:通常在一個事務中執行的所有代碼都會在這個事務中運行。但是,如果一個事務上下文已經存在,有幾個選項可以指定一個事務性方法的執行行為:例如,簡單地在現有的事務中繼續運行(大多數情況);或者掛起現有事務,創建一個新的事務。Spring提供EJB CMT中常見的事務傳播選項。
3:事務超時: 事務在超時前能運行多久(自動被底層的事務基礎設施回滾)。
4:隻讀狀態: 隻讀事務不修改任何數據。隻讀事務在某些情況下(例如當使用Hibernate時),是一種非常有用的優化。
高層次方案:
首選的方法是使用Spring的高層持久化集成API。這種方式不會替換原始的API,而是在內部封裝資源創建、復用、清理、事務同步以及異常映射等功能,這樣用戶的數據訪問代碼就不必關心這些,而集中精力於自己的持久化邏輯。
低層次方案 :
在較低層次上,有以下這些類:DataSourceUtils(針對JDBC),SessionFactoryUtils(針對Hibernate),PersistenceManagerFactoryUtils(針對JDO)等等。也就是說,在純JDBC中,如果你需要使用Spring的事務,那麼就需要使用上面的類來管理連接,如下:
Connection conn=DataSourceUtils.getConnection(dataSource);
當然,一旦你用過Spring的JDBC支持或Hibernate支持,你一般就不再會選擇 DataSourceUtils 或是別的輔助類瞭,因為你會更樂意與Spring抽象一起工作,而不是直接使用相關的API。
Spring框架提供瞭一致的事務管理抽象,通常實施事務的步驟是:
1:定義資源(DataSource/SessionFactory……)
2:定義事務管理器(管理資源的事務)
3:定義事務通知:定義瞭如何實施事務(實施事務的方法名和對應的事務屬性),需要使用事務管理器管理事務,定義瞭如何選擇目標對象的方法及實施的事務屬性
4:定義advisor(切入點和事務通知):切入點選擇需要實施事務的目標對象(通常是業務邏輯層)
5:Spring織入事務通知到目標對象(AOP代理)
要使用Spring的事務,首先要先定義一個與數據源連接的DataSource,然後使用Spring的DataSourceTransactionManager,並傳入指向DataSource的引用,比如,JDBC的事務配置如下:
java代碼:
查看復制到剪貼板打印
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:orcl</value></property>
<property name="username"> <value>test</value> </property>
<property name="password" value="test"/>
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/>
</bean>
如果使用JTA,示例如下:
java代碼:
查看復制到剪貼板打印
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
">
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
</beans>
Hibernate的事務配置,示例如下:
1:Spring對Hibernate的集成
2:然後配置事務如下:
java代碼:
查看復制到剪貼板打印
<bean id="txManager“
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
可以簡單地使用 JtaTransactionManager 來處理Hibernate事務和JTA事務,就像我們處理JDBC,或者任何其它的資源策略一樣,如下:
java代碼:
查看復制到剪貼板打印
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager"/>
註意任何資源的JTA配置都是這樣的,因為它們都是全局事務,可以支持任何事務性資源。在所有這些情況下,應用程序代碼根本不需要做任何改動。僅僅通過改變配置就可以改變事務管理方式,即使這些更改是在局部事務和全局事務間切換。
Spring的聲明式事務管理是通過AOP實現的,Xml風格的聲明式事務配置如下:
java代碼:
查看復制到剪貼板打印
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="myPointCut" expression="execution(* cn.javass.spring3.jdbc.Impl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut"/>
</aop:config>
<bean name="api" class="cn.javass.spring3.jdbc.Impl">
<property name="ds" ref="dataSource"></property>
</bean>
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:orcl</value>
</property>
<property name="username"> <value>ztb</value> </property>
<property name="password" value="ztb"/>
</bean>
</beans>
事務回滾:可以在配置中指定需要回滾的Exception,如下:
java代碼:
查看復制到剪貼板打印
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="false"
rollback-for="NoProductInStockException"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<tx:advice/> 有關的設置,默認的 <tx:advice/> 設置如下:
1:事務傳播設置是 REQUIRED www.aiwalls.com
2:隔離級別是 DEFAULT
3:事務是 讀/寫
4:事務超時默認是依賴於事務系統的,或者事務超時沒有被支持。
5:任何 RuntimeException 將觸發事務回滾,但是任何 checked Exception 將不觸發事務回滾
作者:jinnianshilongnian