程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Spring中的事務管理詳解(重點在於事務管理器),spring事務

Spring中的事務管理詳解(重點在於事務管理器),spring事務

編輯:JAVA綜合教程

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved