XA分散式交易
良葛格在簡介交易中已經把交易的性質說明的很清楚了,要嘛全部成功、要嘛全數陣亡;而distributed transaction(XA)是用來進行全域(global)交易,也就是把一堆交易綁(group)在一起,如同單一交易般具有ACID的特性。
簡單說明Two Phase Commit(2PC)其原則:
- XA以失敗告終,中斷交易
- 準備階段,當所有的XAResource都完成 start() ~ end()後,此階段對每一個XAResource叫用prepare()輪詢,所有輪詢結果必須是XA_OK(準備好等待叫用commit())或是XA_RDONLY(資料未改變,無需叫用commit())
- 若是這階段出現了XAException,coordinator(比如TransactionManager或是寫程式的你)則要負責收攤子(recover(復原),例如網路中斷後又連上了)或是放棄(救不回來了只好forget)
- 完成交易作業
測試程式說明:
第一個測試testRollbackWithRaw():目的在測試第一資料庫塞入一筆”rollback”後再在第二個資料庫塞入一筆”Rollback”資料以引起作業錯誤,然後rollback整個XA交易。
表示不同的格式,0視為使用OSI CCR 格式,我們的測試程式取個大於0的數即可
| |
用來區分不同作業識別
|
通常我們說交易,很多人會認為是指資料庫,其實不然,例如,用戶上傳了一張圖片,我們除了在資料庫中塞入一筆紀錄,也會把圖存起來,但是萬一存圖失敗呢?那就回不去了
所以的處理過程如下:
- 對每一個XAResource叫用TransactionManager.getTransaction().enlistResource(XAResource),相當於對XAResource呼叫了start()
- 對每一個XAResource叫用TransactionManager.getTransaction().delistResource(XAResource),相當於對XAResource呼叫了end()
在隨後的交易測試中加入了檔案讀寫,而檔案的交易使用了XADisk,她的範例中有針對XA交易說明,特別要說明的是XADisk是以目錄為基礎的,也就是說一個XADisk的XAResource必須對應一個目錄。
第三個測試testRollbackWithTxm()使用Atomikos的服務來建立TransactionManager,程式依序加入了兩個資料庫與XADisk的的XAResource,然後在資料庫1塞入了一筆資料,其次將檔案寫入目錄,然後則在資料庫2塞入一筆重覆的資料以引發資料庫錯誤,最後檢查資料庫1的資料有無返回並確認之前寫入的檔案不存在
關於UserTransaction
首先從命名來看,User Transaction,是以用戶角度來看,而不是全域角度出發(在AppServer的應用程式內,用戶沒有理由看到TransactionManager),用戶角度來看用戶從來不需要管理Resource是打那來的(用戶只知道透過JNDI取用資源),所以也無從知道要如何將Resource加入到交易中,用戶只管begin()、commit()或rollback()(Ejb3甚至只要用@TransactionAttribute來宣告即可),所以JEE api 才說TransactionManager是給Applicaton Server用來管理交易,而UserTransaction是讓程式來管理交易的。
真的要抱怨一下JBoss,用過JBoss的都知道其DataSrource的JNDI分為三種形態,大家比較知道的有<local-tx-datasource>與<xa-datasource>(Jboss EAP則為Datasource與XADataSource)。
從名稱上來看讓我誤解若是要做2PC就的宣告為為XADataSource,但是JBoss in Action的3.4.1 Deploying data sources說道:
<local-tx-datasource> Identifies a data source that uses transactions, even distributed transactions within the local application server, but doesn’t use distributed
transactions among multiple application servers.
…If you’re
clustering your application servers or wanting to use distributed transactions among
multiple application servers, then you should use <xa-datasource>.
所以除非要架JBoss Cluster,否則用一般的DataSource就夠了(即使要做2PC)
註:我在JBoss-eap-6.4上測的結果是,若是一般的DataSource,它會警告:
This is transactionally unsafe and should not be relied upon.
所以應該還是用XA-DataSource比較好
|
所以我們只要將資料庫設定為Application Server的Datasource JNDI即可,至於XADisk要如何納入Application Server內管理?只要將XADisk發佈為JCA Resource Adapter即可,在作者者的討論區中有教JBoss與GlassFish(其它的可以直接上去問),不過特別要注意的是,發佈用的檔案必須是從官網上下載的Zip檔中取出的 rar 檔案,不要從其它的發佈到其它地方下載的Jar檔
至於Tomcat使用Atomikos, 官方有教學文(當然也有販售好的整合包),至於Jetty的設定參考這裡,但是XADisk如何在Tomcat或是Jetty裡設定JCA Resource,抱歉,目前為止沒有找到好的解決方法。所以不可避免地,TransactionManager會出現在程式中,也就是說目前除非把XADisk Deploy為JCA,否則就要想辦法在交易開始後呼到
enlistResource(),並在交易結束前對XADisk叫用delistResource()。
至於與Spring的整理,這裡有一篇可以參考, 我也找到一個範例專案,同時作者也在討論區提出了一個範例,請自行參考一下
enlistResource(),並在交易結束前對XADisk叫用delistResource()。
至於與Spring的整理,這裡有一篇可以參考, 我也找到一個範例專案,同時作者也在討論區提出了一個範例,請自行參考一下
留言
張貼留言