posts - 495,  comments - 11,  trackbacks - 0

          6.3 Spring的事務

          Spring的事務管理不需與任何特定的事務API耦合。對不同的持久層訪問技術,編程式事務提供一致的事務編程風格,通過模板化的操作一致性地管理事務。聲明式事務基于Spring AOP實現,卻并不需要程序開發者成為AOP專家,亦可輕易使用Spring的聲明式事務管理。

          6.3.1 Spring支持的事務策略

          Spring事務策略是通過PlatformTransactionManager接口體現的,該接口是Spring事務策略的核心。該接口的源代碼如下:

          public interface PlatformTransactionManager

          {

          ??? //平臺無關的獲得事務的方法

          ??? TransactionStatus getTransaction(TransactionDefinition definition)

          ??????? throws TransactionException;

          ??? //平臺無關的事務提交方法

          ??? void commit(TransactionStatus status) throws TransactionException;

          ??? //平臺無關的事務回滾方法

          ??? void rollback(TransactionStatus status) throws TransactionException;

          }

          PlatformTransactionManager是一個與任何事務策略分離的接口,隨著底層不同事務策略切換,應用必須采用不同的實現類。PlatformTransactionManager接口沒有與任何事務資源捆綁在一起,它可以適應于任何的事務策略,結合Spring的IoC容器,可以向PlatformTransactionManager注入相關的平臺特性。

          PlatformTransactionManager接口有許多不同的實現類,應用程序面向與平臺無關的接口編程,對不同平臺的底層支持,由PlatformTransactionManager接口的實現類完成。從而,應用程序無須與具體的事務API耦合。因此,使用PlatformTransactionManager接口,可將代碼從具體的事務API中解耦出來。

          即使使用特定容器管理的JTA,代碼依然無須執行JNDI查找,無須與特定的JTA資源耦合在一起。通過配置文件,JTA資源傳給PlatformTransactionManager的實現類。因此,程序的代碼可在JTA事務管理和非JTA事務管理之間輕松切換。

          在PlatformTransactionManager接口內,包含一個getTransaction(TransactionDefinition definition)方法,該方法根據一個TransactionDefinition參數,返回一個TransactionStatus對象。TransactionStatus對象表示一個事務。TransactionStatus被關聯在當前執行的線程。

          getTransaction(TransactionDefinition definition)返回的TransactionStatus對象,可能是一個新的事務,也可能是一個已經存在的事務對象。如果當前執行的線程已經處于事務管理下,返回當前線程的事務對象,否則,返回當前線程的調用堆棧已有的事務對象。

          TransactionDefinition接口定義了一個事務規則,該接口必須指定如下幾個屬性值:

          ?? ● 事務隔離,當前事務和其他事務的隔離程度。例如,這個事務能否看到其他事務未提交的數據等。

          ?? ● 事務傳播,通常,在事務中執行的代碼都會在當前事務中運行。但是,如果一個事務上下文已經存在,有幾個選項可指定該事務性方法的執行行為。例如,大多數情況下,簡單地在現有的事務上下文中運行;或者掛起現有事務,創建一個新的事務。Spring提供EJB CMT(Contain Manager Transaction,容器管理事務)中所有的事務傳播選項。

          ?? ● 事務超時,事務在超時前能運行多久。事務的最長持續時間。如果事務一直沒有被提交或回滾,將在超出該時間后,系統自動回滾事務。

          ?? ● 只讀狀態,只讀事務不修改任何數據。在某些情況下(例如使用Hibernate時),只讀事務是非常有用的優化。

          TransactionStatus代表事務本身,它提供了簡單的控制事務執行和查詢事務狀態的方法。這些方法在所有的事務API中都是相同的。TransactionStatus接口的源代碼如下:

          public interface TransactionStatus

          {

          ??? //判斷事務是否是新建的事務

          ??? boolean isNewTransaction();

          ??? //設置事務回滾

          ??? void setRollbackOnly();

          ??? //查詢事務是否已有回滾標志

          ??? boolean isRollbackOnly();

          }

          Spring的事務管理由PlatformTransactionManager的不同實現類完成。在Spring上下文中配置PlatformTransactionManager Bean時,必須針對不同環境提供不同的實現類。

          下面提供不同的持久層訪問環境,及其對應的PlatformTransactionManager實現類的 配置。

          JDBC數據源的局部事務策略:

          <?xml version="1.0" encoding="GBK"?>

          <!-- 指定Spring配置文件的根元素,以及Spring配置文件的Schema信息 -->

          <beans xmlns="http://www.springframework.org/schema/beans"

          ?????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans

          ?????? http://www.springframework.org/schema/beans/spring-beans.xsd">

          <!-- 定義數據源Bean,使用C3P0數據源實現 -->

          <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

          ??? <!-- 指定連接數據庫的驅動 -->

          ??? <property name="driverClass" value="com.mysql.jdbc.Driver"/>

          ??? <!-- 指定連接數據庫的URL -->

          ??? <property name="jdbcUrl" value="jdbc:mysql://localhost/j2ee"/>

          ??? <!-- 指定連接數據庫的用戶名 -->

          ??? <property name="user" value="root"/>

          ??? <!-- 指定連接數據庫的密碼 -->

          ??? <property name="password" value="32147"/>

          ??? <!-- 指定連接數據庫連接池的最大連接數 -->

          ??? <property name="maxPoolSize" value="40"/>

          ??? <!-- 指定連接數據庫連接池的最小連接數 -->

          ??? <property name="minPoolSize" value="1"/>

          ??? <!-- 指定連接數據庫連接池的初始化連接數 -->

          ??? <property name="initialPoolSize" value="1"/>

          ??? <!-- 指定連接數據庫連接池的連接最大空閑時間 -->

          ??? <property name="maxIdleTime" value="20"/>

          </bean>

          <!-- 配置JDBC數據源的局部事務管理器 -->

          <!-- 使用DataSourceTransactionManager 類,該類實現PlatformTransactionManager接口 -->

          <!-- 針對采用數據源連接的特定實現 -->

          <bean id="transactionManager"

          ??????? class="org.springframework.jdbc.datasource.
          ??????? DataSourceTransactionManager">

          ??????? <!-- DataSourceTransactionManager bean需要依賴注入一個DataSource
          ??????? bean的引用 -->

          ??? ???? <property name="dataSource" ref="dataSource"/>

          ??? </bean>

          </beans>

          對于容器管理JTA數據源,全局事務策略的配置文件如下:

          <?xml version="1.0" encoding="GBK"?>

          <!-- 指定Spring配置文件的根元素,以及Spring配置文件的Schema信息 -->

          <beans xmlns="http://www.springframework.org/schema/beans"

          ?????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans

          http://www.springframework.org/schema/beans/spring-beans.xsd">

          ??? <!-- 配置JNDI數據源Bean -->

          ??? <bean id="dataSource" class="org.springframework.jndi.
          ??? JndiObjectFactoryBean">

          ??? <!-- 容器管理數據源的JNDI -->

          ??? ???? <property name="jndiName" value="jdbc/jpetstore"/>

          ??? </bean>

          ??? <!-- 使用JtaTransactionManager類,該類實現PlatformTransactionManager接
          ??? 口 -->

          ??? <!-- 針對采用全局事務管理的特定實現 -->

          ??? <!-- JtaTransactionManager不需要知道數據源,或任何其他特定資源 -->

          ??? <!-- 因為它使用容器的全局事務管理 -->

          ??? <bean id="transactionManager"

          ??????? class="org.springframework.transaction.jta.
          ??????? JtaTransactionManager" />

          </beans>

          對于采用Hibernate持久層訪問策略時,局部事務策略的配置文件如下:

          <?xml version="1.0" encoding="GBK"?>

          <!-- 指定Spring配置文件的根元素,以及Spring配置文件的Schema信息 -->

          <beans xmlns="http://www.springframework.org/schema/beans"

          ?????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans

          http://www.springframework.org/schema/beans/spring-beans.xsd">

          ??? <!-- 定義數據源Bean,使用C3P0數據源實現 -->

          ??? <bean id="dataSource" class="com.mchange.v2.c3p0.
          ??? ComboPooledDataSource" destroy-method="close">

          ??????? <!-- 指定連接數據庫的驅動 -->

          ??? ??? <property name="driverClass" value="com.mysql.jdbc.Driver"/>

          ??????? <!-- 指定連接數據庫的URL -->

          ??? ??? <property name="jdbcUrl" value="jdbc:mysql://localhost/j2ee"/>

          ??????? <!-- 指定連接數據庫的用戶名 -->

          ??? ??? <property name="user" value="root"/>

          ??????? <!-- 指定連接數據庫的密碼 -->

          ??? ??? <property name="password" value="32147"/>

          ??????? <!-- 指定連接數據庫連接池的最大連接數 -->

          ??? ??? <property name="maxPoolSize" value="40"/>

          ??????? <!-- 指定連接數據庫連接池的最小連接數 -->

          ??? ??? <property name="minPoolSize" value="1"/>

          ??????? <!-- 指定連接數據庫連接池的初始化連接數 -->

          ??? ??? <property name="initialPoolSize" value="1"/>

          ??????? <!-- 指定連接數據庫連接池的連接最大空閑時間 -->

          ??? ??? <property name="maxIdleTime" value="20"/>

          ??? </bean>

          ??? <!-- 定義Hibernate的SessionFactory -->

          ??? <bean id="sessionFactory" class="org.springframework.orm.hibernate3.
          ??? LocalSessionFactoryBean">

          ??????? <!-- 依賴注入SessionFactory所需的數據源,正是上文定義的dataSource -->

          ??????? <property name="dataSource" ref="dataSource"/>

          ??????? <!-- mappingResources屬性用來列出全部映射文件 -->

          ??????? <property name="mappingResources">

          ??????????? <list>

          ??????????????? <!-- 以下用來列出所有的PO映射文件 -->

          ??????????????? <value>lee/MyTest.hbm.xml</value>

          ??????????? </list>

          ??????? </property>

          ????????? <!-- 定義Hibernate的SessionFactory的屬性 -->

          ??????? <property name="hibernateProperties">

          ??????? ???? <props>

          ??????????????? <!-- 指定Hibernate的連接方言 -->

          ??????????? ??? <prop key="hibernate.dialect">org.hibernate.dialect.
          ??????????? ??? MySQLDialect</prop>

          ??????????????? <!-- 是否根據Hibernate映射創建數據表時,選擇create、update、
          ??????????????? create-drop -->

          ??????????? ????? <prop key="hibernate.hbm2ddl.auto">update</prop>

          ??????? ???? </props>

          ??????? </property>

          ??? </bean>

          ??? <!-- 配置Hibernate的局部事務管理器 -->

          ??? <!-- 使用HibernateTransactionManager類,該類是PlatformTransactionManager
          ??? 接口,針對采用Hibernate持久化連接的特定實現 -->

          ??? <bean id="transactionManager"

          ??? class="org.springframework.orm.hibernate3.
          ??? HibernateTransactionManager">

          ??????????? <!-- HibernateTransactionManager Bean需要依賴注入一個
          ??????????? SessionFactorybean的引用 -->

          ??? ???? <property name="sessionFactory" ref="sessionFactory"/>

          ???? </bean>

          </beans>

          對于采用Hibernate持久層訪問策略時,全局事務策略的配置文件如下:

          <?xml version="1.0" encoding="GBK"?>

          <!-- 指定Spring配置文件的根元素,以及Spring配置文件的Schema信息 -->

          <beans xmlns="http://www.springframework.org/schema/beans"

          ?????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans

          http://www.springframework.org/schema/beans/spring-beans.xsd">

          ??? <!-- 配置JNDI數據源Bean -->

          ??? <bean id="dataSource" class="org.springframework.jndi.
          ??? JndiObjectFactoryBean">

          ??????? <!-- 容器管理數據源的JNDI -->

          ??? ???? <property name="jndiName" value="jdbc/jpetstore"/>

          ??? </bean>

          ??? <!--定義Hibernate的SessionFactory -->

          ??? <bean id="sessionFactory" class="org.springframework.orm.hibernate3.
          ??? LocalSessionFactoryBean">

          ??????? <!-- 依賴注入SessionFactory所需的數據源,正是上文定義的dataSource Bean -->

          ??????? <property name="dataSource" ref="dataSource"/>

          ??????? <!-- mappingResources屬性用來列出全部映射文件 -->

          ??????? <property name="mappingResources">

          ??????????? <list>

          ??? ????????????? <!-- 以下用來列出所有的PO映射文件 -->

          ??????????????? <value>lee/MyTest.hbm.xml</value>

          ??????????? </list>

          ??????? </property>

          ????????? <!-- 定義Hibernate的SessionFactory的屬性 -->

          ??????? <property name="hibernateProperties">

          ??????? ???? <props>

          ??????????????? <!-- 指定Hibernate的連接方言 -->

          ??????????? ??? <prop key="hibernate.dialect">org.hibernate.dialect.
          ??????????????? MySQLDialect</prop>

          ??????????????? <!-- 是否根據Hiberante映射創建數據表時,選擇create、update、
          ??????????????? create-drop -->

          ??????????? ????? <prop key="hibernate.hbm2ddl.auto">update</prop>

          ??????? ???? </props>

          ???? ???? </property>

          ??? </bean>

          ??? <!-- 使用JtaTransactionManager類,該類是PlatformTransactionManager接口,
          ??????????? 針對采用數據源連接的特定實現 -->

          ??? <!-- JtaTransactionManager不需要知道數據源,或任何其他特定資源,

          ??????????? 因為使用容器的全局事務管理 -->

          ??? <bean id="transactionManager"

          ??????? ?? class="org.springframework.transaction.jta.
          ??????? ?? JtaTransactionManager" />

          </beans>

          不論采用哪種持久層訪問技術,只要使用JTA數據源,Spring事務管理器的配置都是一樣的,因為它們都采用的是全局事務管理。

          可以看到,僅僅通過配置文件的修改,就可以在不同的事務管理策略間切換,即使從局部事務到全局事務的切換。

          提示:Spring所支持的事務策略非常靈活,Spring的事務策略允許應用程序在不同事務策略之間自由切換,即使需要在局部事務策略和全局事務策略之間切換,只需要修改配置文件,而應用程序的代碼無須任何改變。這種靈活的設計,又何嘗不是因為面向接口編程帶來的優勢,可見面向接口編程給應用程序更好的適應性。

          posted on 2009-07-19 10:18 jadmin 閱讀(76) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 齐齐哈尔市| 罗平县| 开远市| 梅河口市| 汪清县| 余庆县| 故城县| 梅州市| 兴和县| 永泰县| 将乐县| 西峡县| 西华县| 盐源县| 龙门县| 庆云县| 望奎县| 泰来县| 彩票| 奉节县| 黄石市| 满洲里市| 宁南县| 乌海市| 西和县| 云梦县| 临猗县| 垫江县| 舒城县| 新兴县| 淮北市| 瓮安县| 德阳市| 赤城县| 全州县| 从江县| 集安市| 十堰市| 昆明市| 洛扎县| 栾城县|