事務管理是企業級應用程序開發中必不可少的技術,用來確保數據的完整性和一致性
事務就是一系列的動作,它們被當作一個單獨的工作單元。這些動作要麼全部完成,要麼全部不起作用
① 原子性(atomicity):事務是一個原子操作,有一系列動作組成。事務的原子性確保動作要麼全部完成,要麼完全不起作用
② 一致性(consistency):一旦所有事務動作完成,事務就被提交。數據和資源就處於一種滿足業務規則的一致性狀態中
③ 隔離性(isolation):可能有許多事務會同時處理相同的數據,因此每個事物都應該與其他事務隔離開來,防止數據損壞
④ 持久性(durability):一旦事務完成,無論發生什麼系統錯誤,它的結果都不應該受到影響。通常情況下,事務的結果被寫到持久化存儲器中
作為企業級應用程序框架,Spring在不同的事務管理API之上定義了一個抽象層。而應用程序開發人員不必了解底層的事務管理API,就可以使用Spring的事務管理機制。
Spring既支持編程式事務管理(也稱編碼式事務),也支持聲明式的事務管理
編程式事務管理:將事務管理代碼嵌入到業務方法中來控制事務的提交和回滾,在編程式事務中,必須在每個業務操作中包含額外的事務管理代碼
聲明式事務管理:大多數情況下比編程式事務管理更好用。它將事務管理代碼從業務方法中分離出來,以聲明的方式來實現事務管理。事務管理作為一種橫切關注點,可以通過AOP方法模塊化。Spring通過Spring AOP框架支持聲明式事務管理。
Spring並不直接管理事務,而是提供了多種事務管理器,它們將事務管理的職責委托給JTA或其他持久化機制所提供的平台相關的事務實現。每個事務管理器都會充當某一特定平台的事務實現的門面,這使得用戶在Spring中使用事務時,幾乎不用關注實際的事務實現是什麼。
Spring提供了許多內置事務管理器實現:
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種傳播行為:
其中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