Spring中的交易管理詳解(重點在於交易管理員),spring事務
Spring中的交易管理詳解 目錄:事務簡介
交易管理是企業級應用程式開發中必不可少的技術,用來確保資料的完整性和一致性
事務就是一系列的動作,它們被當作一個單獨的工作單元。這些動作要麼全部完成,要麼全部不起作用
事務的四個關鍵屬性(ACID)
① 原子性(atomicity):事務是一個原子操作,有一系列動作組成。事務的原子性確保動作要麼全部完成,要麼完全不起作用
② 一致性(consistency):一旦所有事務動作完成,事務就被提交。資料和資源就處於一種滿足商務規則的一致性狀態中
③ 隔離性(isolation):可能有許多事務會同時處理相同的資料,因此每個事物都應該與其他事務隔離開來,防止資料損毀
④ 持久性(durability):一旦事務完成,無論發生什麼系統錯誤,它的結果都不應該受到影響。通常情況下,事務的結果被寫到持久化儲存空間中
Spring中的交易管理
作為企業級應用程式架構,Spring在不同的交易管理API之上定義了一個抽象層。而應用程式開發人員不必瞭解底層的交易管理API,就可以使用Spring的交易管理機制。
Spring既支援編程式交易管理(也稱編碼式事務),也支援聲明式的交易管理
編程式交易管理:將交易管理代碼嵌入到業務方法中來控制事務的提交和復原,在編程式事務中,必須在每個業務操作中包含額外的交易管理代碼
聲明式交易管理:大多數情況下比編程式交易管理更好用。它將交易管理代碼從業務方法中分離出來,以聲明的方式來實現交易管理。交易管理作為一種橫切關注點,可以通過AOP方法模組化。Spring通過Spring AOP架構支援聲明式交易管理。
Spring的交易管理員
Spring並不直接管理事務,而是提供了多種交易管理員,它們將交易管理的職責委託給JTA或其他持久化機制所提供的平台相關的事務實現。每個交易管理員都會充當某一特定平台的事務實現的門面,這使得使用者在Spring中使用事務時,幾乎不用關注實際的事務實現是什麼。
Spring提供了許多內建交易管理員實現:
- DataSourceTransactionManager:位於org.springframework.jdbc.datasource包中,資料來源交易管理員,提供對單個javax.sql.DataSource交易管理,用於Spring JDBC抽象架構、iBATIS或MyBatis架構的交易管理;
- JdoTransactionManager:位於org.springframework.orm.jdo包中,提供對單個javax.jdo.PersistenceManagerFactory交易管理,用於整合JDO架構時的交易管理;
- JpaTransactionManager:位於org.springframework.orm.jpa包中,提供對單個javax.persistence.EntityManagerFactory事務支援,用於整合JPA實現架構時的交易管理;
- HibernateTransactionManager:位於org.springframework.orm.hibernate3包中,提供對單個org.hibernate.SessionFactory事務支援,用於整合Hibernate架構時的交易管理;該交易管理員只支援Hibernate3+版本,且Spring3.0+版本只支援Hibernate 3.2+版本;
- JtaTransactionManager:位於org.springframework.transaction.jta包中,提供對分散式交易管理的支援,並將交易管理委託給Java EE應用伺服器交易管理員;
- OC4JjtaTransactionManager:位於org.springframework.transaction.jta包中,Spring提供的對OC4J10.1.3+應用伺服器交易管理員的適配器,此適配器用於對應用伺服器提供的進階事務的支援;
- WebSphereUowTransactionManager:位於org.springframework.transaction.jta包中,Spring提供的對WebSphere 6.0+應用伺服器交易管理員的適配器,此適配器用於對應用伺服器提供的進階事務的支援;
- WebLogicJtaTransactionManager:位於org.springframework.transaction.jta包中,Spring提供的對WebLogic 8.1+應用伺服器交易管理員的適配器,此適配器用於對應用伺服器提供的進階事務的支援。
Spring不僅提供這些交易管理員,還提供對如JMS交易管理的管理器等,Spring提供一致的事務抽象9-1所示。
圖9-1 Spring交易管理員
接下來讓我們學習一下如何在Spring設定檔中定義交易管理員:
聲明對本地事務的支援:
a)JDBC及iBATIS、MyBatis架構交易管理員
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/></bean>
通過dataSource屬性指定需要交易管理的單個javax.sql.DataSource對象。在幕後DataSourceTransactionManager通過調用java.sql.Connection來管理事務,而後者是通過DataSource擷取到的。通過調用串連的commit()方法來提交事務。同樣,事務失敗時通過調用rollback()方法進行復原。
b)Jdo交易管理員
<bean id="txManager" class="org.springframework.orm.jdo.JdoTransactionManager"> <property name="persistenceManagerFactory" ref="persistenceManagerFactory"/></bean>
通過persistenceManagerFactory屬性指定需要交易管理的javax.jdo.PersistenceManagerFactory對象。
c)Jpa交易管理員
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/></bean>
通過entityManagerFactory屬性指定需要交易管理的javax.persistence.EntityManagerFactory對象。
還需要為entityManagerFactory對象指定jpaDialect屬性,該屬性所對應的對象指定了如何擷取連線物件、開啟事務、關閉事務等交易管理相關的行為。
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> …… <property name="jpaDialect" ref="jpaDialect"/></bean><bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
d)Hibernate交易管理員
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/></bean>
在幕後HibernateTransactionManager將交易管理的職責委託給org.hibernate.Transaction對象,而後者是從Hibernate Session中擷取到的。當事務成功完成時,HibernateTransactionManager將會調用Transaction對象的commit()方法來提交事務。同樣,事務失敗時通過調用Transaction的rollback()方法進行復原。
Spring對全域事務的支援:
a)Jta交易管理員
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"> <jee:jndi-lookup id="dataSource" jndi-name="jdbc/test"/> <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManagerName" value=" java:comp/TransactionManager"/> </bean></beans>
“dataSource”Bean表示從JNDI中擷取的資料來源,而txManager是JTA交易管理員,其中屬性transactionManagerName指定了JTA交易管理員的JNDI名字,從而將交易管理委託給該交易管理員。
定義事務屬性
在Spring中,聲明式事務是通過事務屬性來定義的,事務屬性描述了事務策略如何應用到方法上。事務屬性包含了5個方面,儘管Spring提供了多種聲明式事務的機制,但是所有的方式都依賴這五個參數來控制如何管理事務策略。聲明式事務通過傳播行為,隔離等級,唯讀提示,事務逾時及復原規則來進行定義。
Spring事務的傳播行為:
當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啟一個新事務,並在自己的事務中運行。
事務的傳播行為可以由傳播屬性指定。Spring定義了7種傳播行為:
Spring支援的事務傳播行為
傳播行為 |
含義 |
PROPAGATION_MANDATORY |
表示該方法必須在事務中運行,如果當前事務不存在,則會拋出一個異常 |
PROPAGATION_NESTED |
表示如果當前已經存在一個事務,那麼該方法將會在嵌套事務中運行。嵌套的事務可以獨立於當前事務進行單獨地提交或復原。如果當前事務不存在,那麼其行為與PROPAGATION_REQUIRED一樣。注意各廠商對這種傳播行為的支援是有所差異的。可以參考資源管理員的文檔來確認它們是否支援嵌套事務 |
PROPAGATION_NEVER |
表示當前方法不應該運行在事務上下文中。如果當前正有一個事務在運行,則會拋出異常 |
PROPAGATION_NOT_SUPPORTED |
表示該方法不應該運行在事務中。如果存在當前事務,在該方法運行期間,當前事務將被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager |
PROPAGATION_REQUIRED |
表示當前方法必須運行在事務中。如果當前事務存在,方法將會在該事務中運行。否則,會啟動一個新的事務 |
PROPAGATION_REQUIRED_NEW |
表示當前方法必須運行在它自己的事務中。一個新的事務將被啟動。如果存在當前事務,在該方法執行期間,當前事務會被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager |
PROPAGATION_SUPPORTS |
表示當前方法不需要事務上下文,但是如果存在當前事務的話,那麼該方法會在這個事務中運行 |
其中PROPAGATION_REQUIRED為預設的傳播屬性
Spring事務的隔離等級
隔離等級定義了一個事務可能受其他並發事務影響的程度。在典型的應用程式中,多個事務並發運行,經常會操作相同的資料來完成各自的任務。並發,雖然是必須的,可是會導致下面的問題。
並發事務所導致的問題可以分為以下三類:
① 髒讀(Dirty reads):髒讀發生在一個事務讀取了另一個事務改寫但尚未提交的資料時。如果改寫在稍後被復原了,那麼第一個事務擷取的資料就是無效的。
② 不可重複讀取(Nonrepeatable read):不可重複讀取發生在一個事務執行相同的查詢兩次或兩次以上,但是每次都得到不同的資料時。這通常是因為另一個並發事務在兩次查詢期間更新了資料
③ 幻讀(Phantom read):幻讀與不可重複讀取類似。它發生在一個事務(T1)讀取了幾行資料,接著另一個並發事務(T2)插入了一些資料時。在隨後的查詢中,第一個事務(T1)就會發現多了一些原本不存在的記錄
Spring事務的隔離等級
1. ISOLATION_DEFAULT: 這是一個PlatfromTransactionManager預設的隔離等級,使用資料庫預設的交易隔離等級.
另外四個與JDBC的隔離等級相對應
2. ISOLATION_READ_UNCOMMITTED: 這是事務最低的隔離等級,它充許令外一個事務可以看到這個事務未提交的資料。
這種隔離等級會產生髒讀,不可重複讀取和幻像讀。
3. ISOLATION_READ_COMMITTED: 保證一個事務修改的資料提交後才能被另外一個事務讀取。另外一個事務不能讀取該事務未提交的資料
4. ISOLATION_REPEATABLE_READ: 這種交易隔離等級可以防止髒讀,不可重複讀取。但是可能出現幻像讀。
它除了保證一個事務不能讀取另一個事務未提交的資料外,還保證了避免下面的情況產生(不可重複讀取)。
5. ISOLATION_SERIALIZABLE 這是花費最高代價但是最可靠的交易隔離等級。事務被處理為順序執行。
除了防止髒讀,不可重複讀取外,還避免了幻像讀。
Spring事務的唯讀
“唯讀事務”並不是一個強制選項,它只是一個“暗示”,提示資料庫驅動程式和資料庫系統,這個事務並不包含更改資料的操作,那麼JDBC驅動程式和資料庫就有可能根據這種情況對該事務進行一些特定的最佳化,比方說不安排相應的資料庫鎖,以減輕事務對資料庫的壓力,畢竟事務也是要消耗資料庫的資源的。“唯讀事務”僅僅是一個效能最佳化的推薦配置而已,並非強制你要這樣做不可。
Spring事務的事務逾時
為了使應用程式更好的運行,事務不能運行太長的時間。因此,聲明式事務的第四個特性就是逾時。
Spring事務的復原規則
預設情況下,事務只有在遇到運行期異常時才會復原,而在遇到檢查型異常時不會復原,但是也可以聲明事務在遇到特定的檢查型異常時像遇到運行期異常那樣復原。同樣,你還可以聲明事務遇到特定的異常不復原,即使這些異常是運行期異常。
文章出自:http://www.cnblogs.com/longshiyVip/p/5061637.html