posts - 66,  comments - 11,  trackbacks - 0

              在軟件中,要么全有要么全無的操作成為事務。事務允許你把幾個操作組成一個單一的工作單元,這個工作單元要么全部發生要么全部不發生。如果每件事都順利,那么這個事務是成功的。但是如果任何一件事情出錯的話,那么已經發生的行為就被清除掉,就像什么事情都沒發生一樣。
              Spring對事務管理有豐富的支持,程序控制的和聲明式的。
              原子性(Atomic):事務由一個或多個行為綁定在一起組成,好像是一個單獨工作單元。原子性確保在十五中的所有操作要么都發生,要么都不發生。
              一致性(Consistent):一旦一個事務結束了(不管成功失敗),系統所處的狀態和它的業務規則是一致的。就是說數據應當不會被破壞。
              隔離性(Isolated):事務應該允許多個用戶操作同一數據,一個用戶的操作不會和其他用戶的操作相混淆。因此,事務必須是互相隔離的,防止并發讀寫同一數據的情況發生。
              持久性(Durable):一旦事務完成,事務的結果應該持久化,這樣不管什么樣的系統崩潰,他們都將幸免于難。
           
              Spring對程序控制事務管理的支持和EJB的有很大不同。EJB的事務管理和JTA密不可分,和EJB不同的是,Spring使用了一種回調機制,把真實的事務實現從事務代碼中抽象出來。選擇程序控制事務管理還是聲明式事務管理,很大程度上是在細粒度控制與簡便操作之間做出決定。當你在代碼中編寫事務時,你能精確控制事務的邊界,在你希望的地方精確的開始和結束。典型的情況下,你不需要程序控制事務所提供的細粒度控制,你會選擇在上下文定義文件中聲明你的事務。

              Spring對聲明式事務管理的支持是通過它的AOP框架實現的。這樣做是非常自然的,因為事務是系統級的,凌駕于應用的主要功能之上的。

              在Spring里,事務屬性是對事務策略如何應用到方法的描述。這個描述包括:傳播行為、隔離級別、只讀提示、事務超時間隔
              傳播行為:
              PROPAGATION_MANDATORY:表示該方法必須運行在一個事務中。如果當前事務不存在,將拋出一個異常。
              PROPAGATION_NESTED:表示如果當前已經存在一個事務,則該方法應當運行在一個嵌套的事務中。被嵌套的事務可以從當前事務中單獨的提交或回滾。如果當前事務不存在,那么它看起來和PROPAGATION_REQUIRED沒有兩樣。
              PROPAGATION_NEVER:表示當前的方法不應該運行在一個事務上下文中。如果當前存在一個事務,則會拋出一個異常。
              PROPAGATION_NOT_SUPPORTED:表示該方法不應在事務中運行。如果一個現有的事務正在運行中,它將在該方法的運行期間被掛起。
              PROPAGATION_REQUIRED:表示當前方法必須運行在一個事務中。如果一個現有的事務正在運行中,該方法將運行在這個事務中。否則的話,要開始一個新的事務。
              PROPAGATION_REQUIRES_NEW:表示當前方法必須運行在它自己的事務里。它將啟動一個新的事務。如果有事務運行的話,將在這個方法運行期間被掛起。
              PROPAGATION_SUPPORTS:表示當前方法不需要事務處理環境,但如果有一個事務已經在運行的話,這個方法也可以在這個事務里運行。

             傳播規則回答了一個問題:就是新的事務是否要被啟動或是被掛起,或者方法是否要在事務環境中運行。

             隔離級別:在一個典型的應用中,多個事務并發運行,經常會操作同一個數據來完成它們的任務。并發,雖然是必須的,但會導致下面問題:
          1、臟讀:臟讀發生在一個事務讀取了被另一個事務改寫但還未提交的數據時。如果這些改變在稍后被回滾,那么第一個事務讀取的數據就是無效的。
          2、不可重復讀:不可重復讀發生在一個事務執行相同的查詢2次或2次以上,但每一次查詢結果都不同時。這通常是由于另一個并發事務在2次查詢之間更新了數據。
          3、幻讀:幻讀和不可重復讀相似。當一個事務讀取幾行紀錄后,另一個并發事務插入一些記錄,幻讀就發生了。隔離級別有如下幾個:
          ISOLATION_DEFAULT:使用后端數據庫默認的隔離級別
          ISOLATION_READ_UNCOMMITTED:允許你讀取還未提交的改變了的數據,可能導致臟讀、幻讀、不可重復讀
          ISOLATION_READ_COMMITTED:允許在并發事務已經提交后讀取。可防止臟讀,但幻讀和不可重復讀仍可能發生。
          ISOLATION_REPEATABLE_READ:對相同字段的多次讀取的結果是一致的,除非數據被事務本身改變。可防止臟讀和不可重復讀,但幻讀仍可能發生。
          ISOLATION_SERIALIZABLE:完全服從ACID的隔離級別,確保不發生臟讀、不可重復讀和幻讀。這在所有隔離級別中也是最慢的。

              只讀:如果一個事務只對后端是據庫執行讀操作,數據庫就可能利用事務只讀的特性,使用某些優化措施。通過聲明一個事務為只讀,你就給了后端數據庫一個機會,來應用那些它認為合適的優化措施。因為只讀的優化措施是在事務啟動時由后端數據庫實施的,所以,只有將那些具有可能啟動新事務的傳播行為的方法的事務標記成只讀才有意義(PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED) TransactionProxyFactoryBean參照一個方法的事務屬性,決定如何在那個方法上執行事務策略。

          <?xml version="1.0" encoding="UTF-8"?>
          <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-2.0.xsd">
              
          <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
                  
          <property name="jndiName">
                      
          <value>java:comp/env/jdbc/myDatasource</value>
                  
          </property>
              
          </bean>
              
          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                  
          <property name="dataSource">
                      
          <ref bean="dataSource"/>
                  
          </property>
              
          </bean>
              
          <!-- 這個對象有一個值為courseService的id.當應用從應用上下文里請求一個courseService時,它將得到一個被
              TransactionProxyFactoryBean包裹的實例。 
          -->
              
          <bean id="courseService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
                  
          <!-- 代理所實現的接口 -->
                  
          <property name="proxyInterfaces">
                      
          <list>
                          
          <value>
                              com.springinaction.training.service.CourseService
                          
          </value>
                      
          </list>
                  
          </property>
                  
          <!-- 被代理的對象 -->
                  
          <property name="target">
                      
          <ref bean="courseServiceTarget"/>
                  
          </property>
                  
          <!-- 事務管理器 -->
                  
          <property name="transactionManager">
                      
          <ref bean="transactionManager"/>
                  
          </property>
                  
          <!-- 事務的屬性源 -->
                  
          <property name="transactionAttributeSource">
                      
          <ref bean="transactionAttributeSource"/>
                  
          </property>
              
          </bean>
              
          <!-- 要知道盡管可以改變MatchAlwaysTransactionAttributeSource的事務屬性參數,但它總是返回相同的事務屬性,而
              不關心參與交易的哪一個方法。當你有一個相對簡單的應用,把同樣的事務策略應用到所有方法都沒問題時,使用MatchAlwaysT
              ransactionAttributeSource就相當好。但是,在那些更為復雜的應用中,你很可能需要對不同的方法應用不同的事務策略。在那樣
              情況下,你需要在應用何種策略的問題上做更多精確的控制。 
          -->
              
          <bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
                  
          <property name="transactionAttribute">
                      
          <ref bean="myTransactionAttribute"/>
                  
          </property>
              
          </bean>
              
          <!-- 定義事務策略 -->
              
          <bean id="myTransactionAttribute" class="org.springframework.transaction.interceptor.DefaultTransactionAttribute">
                  
          <!-- 傳播行為 -->
                  
          <property name="propagationBehaviorName">
                      
          <value>PROPAGATION_REQUIRES_NEW</value>
                  
          </property>
                  
          <!-- 隔離級別 -->
                  
          <property name="isolationLevelName">
                      
          <value>ISOLATION_REPEATABLE_READ</value>
                  
          </property>
              
          </bean>
          </beans>

           

          除了將transactionAttributeSource對象織入到TransactionProxyFactoryBean的transactionAttributeSource屬性中外,還有一種簡單的方法。發展到現在,TransactionProxyFactoryBean也有一個transactionAttributes屬性為transactionProperties.

          <?xml version="1.0" encoding="UTF-8"?>
          <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-2.0.xsd">
              
          <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
                  
          <property name="jndiName">
                      
          <value>java:comp/env/jdbc/myDatasource</value>
                  
          </property>
              
          </bean>
              
          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                  
          <property name="dataSource">
                      
          <ref bean="dataSource"/>
                  
          </property>
              
          </bean>
              
          <!-- 這個對象有一個值為courseService的id.當應用從應用上下文里請求一個courseService時,它將得到一個被
              TransactionProxyFactoryBean包裹的實例。 
          -->
              
          <bean id="courseService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
                  
          <!-- 代理所實現的接口 -->
                  
          <property name="proxyInterfaces">
                      
          <list>
                          
          <value>
                              com.springinaction.training.service.CourseService
                          
          </value>
                      
          </list>
                  
          </property>
                  
          <!-- 被代理的對象 -->
                  
          <property name="target">
                      
          <ref bean="courseServiceTarget"/>
                  
          </property>
                  
          <!-- 事務管理器 -->
                  
          <property name="transactionManager">
                      
          <ref bean="transactionManager"/>
                  
          </property>
                  
          <!-- 事務的屬性源 -->
                  
          <property name="transactionAttributeSource">
                      
          <ref bean="transactionAttributeSource"/>
                  
          </property>
              
          </bean>
              
          <!-- NameMatchTransactionAttributeSource的properties屬性把方法名映射到事務屬性描述器上。注意CourseException
              用一個負號標記。異常可以用負號或正號標記,當負號異常拋出時,將觸發回滾;相反的,正號異常表示事務仍可提交,即使這個異常拋出 
          -->
              
          <bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
                  
          <property name="properties">
                      
          <props>
                          
          <prop key="enrollStudentInCourse">
                              PROPAGATION_REQUIRES_NEW,ISOLATION_REPEATABLE_READ,readOnly,
                              -CourseException
                          
          </prop>
                          
          <!-- 還可以使用通配符 -->
                          
          <prop key="get*">
                              PROPAGATION_SUPPORTS
                          
          </prop>
                      
          </props>
                  
          </property>
              
          </bean>
          </beans>

           

           

          posted on 2009-11-22 11:43 王永慶 閱讀(261) 評論(0)  編輯  收藏 所屬分類: SPRING
          <2009年11月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          關注blogs

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 丹凤县| 青铜峡市| 泉州市| 临颍县| 阳东县| 泽州县| 兰溪市| 临城县| 时尚| 托克逊县| 衡水市| 桓仁| 天峻县| 保康县| 图们市| 安西县| 玉山县| 安顺市| 金华市| 台前县| 阿克苏市| 泰顺县| 邻水| 姚安县| 手机| 白水县| 涿州市| 亳州市| 尉氏县| 普格县| 比如县| 安新县| 健康| 巍山| 当雄县| 彭泽县| 顺平县| 昌宁县| 安阳市| 台湾省| 雅江县|