JPA和分布式事務簡介


1. Transaction 分兩種,Local Transaction 和 Global Transaction。 
涉及到一個Connection的Commit,稱為Local Transaction。 
涉及到多個Connection的Commit,稱為Global Transaction。 
樓主提到的是,Global Transaction. 

2. Global Transaction 需要XA接口(包括在JTA里面)的支持。 

import javax.sql.XAConnection; 
import javax.transaction.xa.Xid; 
import javax.transaction.xa.XAResource; 
import javax.transaction.xa.XAException; 
import javax.transaction.Transaction; 
import javax.transaction.TransactionManager; 

其中的 
javax.sql.XAConnection; 
javax.transaction.xa.Xid; 
javax.transaction.xa.XAResource; 

這些XA接口的實現,需要數據庫的JDBC提供。 
數據庫本身要支持XA。數據庫的JDBC也要提供XA的實現。 

Oracle, Sybase, DB2, SQL Server等大型數據庫才支持XA, 支持Global Transaction。 
My SQL 連Local Transaction都支持不好,更別說Global Transation了。 

3. XA需要兩階段提交 -- prepare 和 commit. 
假設有兩個Connection, con1, con2, 大體的過程如下, 

con1 = XAResouce1.getConnection...
con2 = XAResouce2.getConnection...

con1 do some thing.
con2 do some thing.
after they finish.

pre1 = XAResouce1.prepare();
pre2 = XAResouce2.prepare();

if( both pre1 and pre2 are OK){
XAResouce1 and 2 commit
}else {
XAResouce1 and 2 rollback
}

前面有人講了,在XAResouce1 and 2 commit的時候, 
可能XAResouce1 commit() 成功了,XAResouce2 commit()失敗了。 
這時候,會拋出一個 “啟發式異常”。程序可以處理這個異常。比如,XAResouce.recover()之類。 
但一般情況下,還真沒別的辦法,需要數據管理員根據數據操作日志 undo所有的操作,或者恢復數據備份。 
有的數據庫在進行數據操作的時候,會生成一個“反操作”日志。比如,insert 對 delete, 等。 

4. TransactionManager的實現能夠處理多個XAResouce(一個XAResouce list)的情況。 
比如Tyrex。或JBoss等EJB Server的Transaction實現代碼

 

注釋:XA:XA協議由Tuxedo首先提出的,並交給X/Open組織,作為資源管理器(數據庫)與事務管理器的接口標准。目前,Oracle、Informix、DB2和Sybase等各大數據庫廠家都提供對XA的支持。XA協議采用兩階段提交方式來管理分布式事務。XA接口提供資源管理器與事務管理器之間進行通信的標准接口。XA協議包括兩套函數,以xa_開頭的及以ax_開頭的。

以下的函數使事務管理器可以對資源管理器進行的操作:

  1)xa_open,xa_close:建立和關閉與資源管理器的連接。

  2)xa_start,xa_end:開始和結束一個本地事務。

  3)xa_prepare,xa_commit,xa_rollback:預提交、提交和回滾一個本地事務。

  4)xa_recover:回滾一個已進行預提交的事務。

  5)ax_開頭的函數使資源管理器可以動態地在事務管理器中進行注冊,並可以對XID(TRANSACTION IDS)進行操作。

  6)ax_reg,ax_unreg;允許一個資源管理器在一個TMS(TRANSACTION MANAGER SERVER)中動態注冊或撤消注冊。

 

 

JTA和JTS

 

JTA

 

JTA定義了一套接口,其中約定了幾種主要的角色:TransactionManager、UserTransaction、Transaction、XAResource,並定義了這些 角色之間需要遵守的規范,如Transaction的委托給TransactionManager等。

 

JTS

 

JTS也是一組規范,上面提到JTA中需要角色之間的交互,那應該如何交互?JTS就是約定了交互細節的規范。

 

總體上來說JTA更多的是從框架的角度來約定程序角色的接口,而JTS則是從具體實現的角度來約定程序角色之間的接口,兩者各司其職。

 

因為JTA相對來說,更高層一些,我們主要關注JTA。

 

XA

 

XA協議,規定事務管理器和資源管理器接口,采用二階段提交協議。

JTA事務有效的屏蔽了底層事務資源,但是與本地事務相比,XA協議的系統開銷大。

 

 

總結

 

關鍵接口

 

先介紹一下JTA的規范接口中,主要圍繞以下幾個接口:

 

  • UserTransaction:編程人員接口
  • TransactionManager:留給廠商實現的與事務管理有關的接口
  • Transaction:留給廠商實現的事務
  • XAResource:留給廠商實現的與持久化資源有關的接口

 

接口類中的接口定義可參見源碼,幾個接口類關系如下:

下載了JBoss的JTA實現源碼,但是發現深入這個源碼有難度,且需要的時間也會較長,故留着以后學習。JBoss的JTA實現是Narayana,SVN地址為https://github.com/jbosstm/narayana,如果有興趣可以研究一下。

二階段提交協議

所以在一階段協議的基礎上,有了二階段協議,二階段協議的好處是添加了一個管理者角色,如下:

很明顯,二階段協議通過將兩層變為三層,增加了中間的管理者角色,從而協調多個數據源之間的關系,二階段提交協議分為兩個階段。

應用程序調用了事務管理器的提交方法,此后第一階段分為兩個步驟:

  • 事務管理器通知參與該事務的各個資源管理器,通知他們開始准備事務。
  • 資源管理器接收到消息后開始准備階段,寫好事務日志並執行事務,但不提交,然后將是否就緒的消息返回給事務管理器(此時已經將事務的大部分事情做完,以后的內容耗時極小)。

第二階段也分為兩個步驟:    

  • 事務管理器在接受各個消息后,開始分析,如果有任意其一失敗,則發送回滾命令,否則發送提交命令。
  • 各個資源管理器接收到命令后,執行(耗時很少),並將提交消息返回給事務管理器。
    事務管理器接受消息后,事務結束,應用程序繼續執行。
    為什么要分兩步執行?一是因為分兩步,就有了事務管理器統一管理的機會;二盡可能晚地提交事務,讓事務在提交前盡可能地完成所有能完成的工作,這樣,最后的提交階段將是耗時極短,耗時極短意味着操作失敗的可能性也就降低。
    同時,二階段提交協議為了保證事務的一致性,不管是事務管理器還是各個資源管理器,每執行一步操作,都會記錄日志,為出現故障后的恢復准備依據。
    二階段提交協議的存在的弊端是阻塞,因為事務管理器要收集各個資源管理器的響應消息,如果其中一個或多個一直不返回消息,則事務管理器一直等待,應用程序也被阻塞,甚至可能永久阻塞。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM