標籤:
在一個典型的交易處理情境中,有以下幾個參與者:
-
Resource Manager(RM)
-
ResourceManager簡稱RM,它負責儲存並管理系統資料資源的狀態,比如資料庫伺服器,JMSMessage Service器等都是相應的Resource Manager。
-
Transaction Processing Monitor(TP Monitor)
-
Transaction Processing Monitor簡稱TPM或者TP Monitor,它的職責是在分散式交易情境中協調包含多個RM的交易處理。TP Monitor通常對應特定的軟體中介軟體(Middleware), 隨著軟體開發技術的進步,TP Monitor的實現也由原來基於過程式的設計與實現轉向物件導向的更趨模組化的設計和實現。J2EE規範[4]中的應用伺服器(Application Server)通常擔當的就是TP Monitor的角色。
-
Transaction Manager(TM)
-
Transaction Manager簡稱為TM,它可以認為是TP Monitor中的核心模組,直接負責多RM之間的交易處理的協調工作,並且提供事務界定(Transaction Demarcation)[5], 事務上下文傳播(transaction context propagation)[6]等功能介面。
-
Application
-
以獨立形式存在的或者運行於容器中的應用程式,可以認為是事務邊界的觸發點。
實際上,並非每一個事務的情境中都會出現以上提到的所有參與者,如果我們根據整個事務中牽扯的RM的多寡來區分事務類型的話,可以將事務分為兩類,即全域事務(Global Transaction)和局部事務(Local Transaction),在這兩類事務中,具體的事務參與者是不同的.
局部事務與全域事務的主要區分在於“事務”中牽扯多少RM,而不是“系統”中實際有多少RM,這是需要我們注意的地方。 即使你系統中存在多個資料庫(即RM),只要你當前事務只更新一個資料庫的資料,那當前事務就依然應該算作局部事務,而不是全域事務(雖然這種情況下,你也可以啟用全域事務)。
實際上,針對單一事務資源的交易管理,你可以在局部事務中直接使用RM內建的事務支援來進行,你也可以引入TP Monitor在分散式交易情境中進行,通常情況下, 各TP Monitor在實現的時候會檢測參與事務的RM數目,如果只有單一的RM參與,TP Monitor會做一定的最佳化,避免採用“兩階段交易認可”協議的負擔, 但即使如此,針對單一事務資源參與的事務,直接採用局部事務中RM內建的事務支援,無論是從複雜度,還是從效率上來看,都要更勝一籌。
在Java的局部事務情境中,系統中交易管理的具體處理方式會隨著所使用的資料訪問技術的不同而各異,我們不是使用專用的事務API來管理事務, 而是通過當前使用的資料訪問技術所提供的基於“connection” [7] 的API來管理事務。
Java平台上的分散式交易管理主要是通過Java Transaction API(JTA)或者Java Connector Architecture(JCA)提供支援的。
JTA是Sun提出的標準化分散式交易訪問的Java介面規範。不過,JTA規範定義的只是一套Java介面定義,具體的實現留給了相應的供應商去實現,各JavaEE應用伺服器需要提供對JTA的支援, 另外,除了可以使用綁定到各JavaEE應用伺服器的JTA實現之外,Java平台上也存在幾個獨立的並且比較成熟的JTA實現產品,這包括:
JOTM(http://jotm.objectweb.org/index.html)
AtomikosAtomikos(http://www.atomikos.com/home.html)
JBoss Transactions(http://labs.jboss.com/jbosstm/)
使用JTA進行分散式交易管理通常有兩種方式,直接使用JTA介面的編程交易管理以及基於應用伺服器的聲明性交易管理。
spring的事務架構將開發過程中交易管理相關的關注點進行適當的分離,並對這些關注點進行合理的抽象,最終打造了一套使用方便卻功能強大的交易管理“利器”。 通過spring的事務架構,我們可以按照統一的編程模型來進行事務編程,卻不用關心所使用的資料訪問技術以及具體要訪問什麼類型的事務資源; 並且,spring的事務架構與spring提供的資料訪問支援可以緊密結合,更是讓你在交易管理與資料訪問之間遊刃有餘,而最主要的,結合spring的AOP架構, spring的事務架構為我們帶來了只有CMT才有的使用聲明式交易管理的待遇,卻無需綁定到任何的應用伺服器上。
spring的事務抽象包括三個主要介面,即PlatformTransactionManager,TransactionDefinition以及TransactionStatus,三介面以org.springframework.transaction.PlatformTransactionManager為中心,org.springframework.transaction.PlatformTransactionManager負責界定事務邊界,org.springframework.transaction.TransactionDefinition負責定義事務相關屬性,包括隔離等級,傳播行為等, org.springframework.transaction.PlatformTransactionManager將參照org.springframework.transaction.TransactionDefinition的屬性定義來開啟相關事務,事務開啟之後到事務結束期間的事務狀態由org.springframework.transaction.TransactionStatus負責, 我們也可以通過org.springframework.transaction.TransactionStatus對事務進行有限的控制。
TransactionDefinition針對事務的傳播行為提供了以下幾種選擇,除了PROPAGATION_NESTED是spring特有的外,其他的傳播行為的語義與CMT基本相同:
PROPAGATION_REQUIRED. 如果當前存在一個事務,則加入當前事務;如果不存在任何事務,則建立一個新的事務。總之,要至少保證在一個事務中運行。PROPAGATION_REQUIRED通常作為預設的事務傳播行為。
PROPAGATION_SUPPORTS. 如果當前存在一個事務,則加入當前事務;如果當前不存在事務,則直接執行。 對於一些查詢方法來說,PROPAGATION_SUPPORTS通常是比較合適的傳播行為選擇。 如果當前方法直接執行,那麼不需要事務的支援;如果當前方法被其他方法調用,而其他方法啟動了一個事務的時候,使用PROPAGATION_SUPPORTS可以保證當前方法能夠加入當前事務並洞察當前事務對資料資源所做的更新。 比如說,A.service()會首先更新資料庫,然後調用B.service()進行查詢,那麼,B.service()如果是PROPAGATION_SUPPORTS的傳播行為, 就可以讀取A.service()之前所做的最新更新結果,而如果使用稍後所提到的PROPAGATION_NOT_SUPPORTED,則B.service()將無法讀取最新的更新結果,因為A.service()的事務在這個時候還沒有提交(除非隔離等級是read uncommitted):
PROPAGATION_MANDATORY. PROPAGATION_MANDATORY強制要求當前存在一個事務,如果不存在,則拋出異常。 如果某個方法需要事務支援,但自身又不管理事務提交或者復原的時候,比較適合使用PROPAGATION_MANDATORY。 你可以參照《JAVA TRANSACTION DESIGN STRATEGIES》一書中對REQUIRED和MANDATORY兩種傳播行為的比較來更深入的瞭解PROPAGATION_MANDATORY的可能應用情境。
PROPAGATION_REQUIRES_NEW. 不管當前是否存在事務,都會建立新的事務。如果當前存在事務的話,會將當前的事務掛起(suspend)。 如果某個業務對象所做的事情不想影響到外層事務的話,PROPAGATION_REQUIRES_NEW應該是合適的選擇,比如,假設當前的業務方法需要向資料庫中更新某些日誌資訊, 但即使這些日誌資訊更新失敗,我們也不想因為該業務方法的交易回復而影響到外層事務的成功提交,因為這種情況下,當前業務方法的事務成功與否對外層事務來說是無關緊要的。
PROPAGATION_NOT_SUPPORTED. 不支援當前事務,而是在沒有事務的情況下執行。如果當前存在事務的話,當前事務原則上將被掛起(suspend),但要依賴於對應的PlatformTransactionManager實作類別是否支援事務的掛起(suspend),更多情況請參照TransactionDefinition的javadoc文檔。 PROPAGATION_NOT_SUPPORTED與PROPAGATION_SUPPORTS之間的區別,可以參照PROPAGATION_SUPPORTS部分的執行個體內容。
PROPAGATION_NEVER. 永遠不需要當前存在事務,如果存在當前事務,則拋出異常。
PROPAGATION_NESTED. 如果存在當前事務,則在當前事務的一個嵌套事務中執行,否則與PROPAGATION_REQUIRED的行為類似,即建立新的事務,在新建立的事務中執行。 PROPAGATION_NESTED粗看起來好像與PROPAGATION_REQUIRES_NEW的行為類似,實際上二者是有差別的。 PROPAGATION_REQUIRES_NEW建立的新事務與外層事務屬於同一個“檔次”,即二者的地位是相同的,當新建立的事務啟動並執行時候,外層事務將被暫時掛起(suspend); 而PROPAGATION_NESTED建立的嵌套事務則不然,它是寄生於當前外層事務的,它的地位比當前外層事務的地位要小一號,當內部嵌套事務啟動並執行時候,外層事務也是出於active狀態:
也就是說,PROPAGATION_REQUIRES_NEW新建立的事務雖然是在當前外層事務內執行,但新建立的事務是獨立於當前外層事務而存在的,二者擁有各自獨立的狀態而互不干擾; 而PROPAGATION_NESTED建立的事務屬於當前外層事務的內部子事務(sub-transaction),內部子事務的處理內容屬於當前外層事務的一部分,而不能獨立於外層事務而存在,並且與外層事務共有事務狀態,我想這也就是為什麼稱其為內部嵌套事務的原因。PROPAGATION_NESTED可能的應用情境在於,你可以將一個大的事務劃分為多個小的事務來處理,並且外層事務可以根據各個內部嵌套事務的執行結果來選擇不同的執行流程。 比如,某個業務對象的業務方法A.service()可能調用其他業務方法B.service()向資料庫中插入一批業務資料,但當插入資料的業務方法出現錯誤的時候(比如主鍵衝突),我們可以在當前事務中捕捉前一個方法拋出的異常,然後選擇另一個更新資料的業務方法C.service()來執行, 這個時候,我們就可以把B.service()和C.serivce()方法的傳播行為指定為PROPAGATION_NESTED
不過,並非所有的PlatformTransactionManager實現都支援PROPAGATION_NESTED類型的傳播行為,現在只有org.springframework.jdbc.datasource.DataSourceTransactionManager在使用JDBC3.0資料庫驅動的情況下才支援(當然,資料庫和相應的驅動程式也需要提供支援),另外, 某些JtaTransactionManager也可能提供支援,但JTA規範並沒有要求提供對嵌套事務的支援。PlatformTransactionManager是spring事務抽象架構的核心組件,關於它的定義以及作用我們之前已經提過了,所以,這部分我們不妨更多的關注一下PlatformTransactionManager整個的層次體系以及針對不同資料訪問技術的實作類別。
PlatformTransactionManager整個的抽象體系基於Strategy模式,由PlatformTransactionManager對事務界定進行統一抽象,而具體的界定策略的實現則交由具體的實作類別。 下面我們先來看一下有哪些實作類別可供我們使用.
PlatformTransactionManager的實作類別可以劃分到面向局部事務和面向全域事務兩個分支:
面向局部事務的PlatformTransactionManager實作類別. spring為各種資料訪問技術提供了現成的PlatformTransactionManager實現支援,以下列表給出了各種資料訪問技術與它們對應的實作類別的關係:
資料訪問技術 |
PlatformTransactionManager實作類別 |
JDBC/iBatis |
DataSourceTransactionManager |
Hibernate |
HibernateTransactionManager |
JDO |
JdoTransactionManager |
JPA(Java Persistence API) |
JpaTransactionManager |
TopLink |
TopLinkTransactionManager |
JMS |
JmsTransactionManager |
JCA Local Transaction |
CciLocalTransactionManager |
在這些實作類別當中,CciLocalTransactionManager可能是比較少見的實現,CCI的意思是Common Client Interface, CciLocalTransactionManager主要是面向JCA的局部事務(Local Transaction),本書不打算對JCA的整合做過多的闡述,讀者如果在實際項目中需要使用到JCA進行EIS(Enterprise Information System)系統整合,你可以從spring的參考文檔獲得使用spring提供的JCA整合支援的足夠資訊。有了這些實作類別,我們在使用spring的事務抽象架構進行交易管理的時候,只需要根據當前使用的資料訪問技術選擇對應的PlatformTransactionManager實作類別即可。
摘自:http://www.cnblogs.com/superjt/archive/2013/05/20/3088847.html
2015第24周三Spring事務3