1、分布式事務(wù)相關(guān)概念
分布式事務(wù)處理(Distributed Transaction Processing,DTP)是指一個(gè)事務(wù)可能涉及多個(gè)數(shù)據(jù)庫(kù)操作,分布式事務(wù)處理的關(guān)鍵是必須有一種方法可以知道事務(wù)在任何地方所做的所有動(dòng)作,提交或回滾事務(wù)的決定必須產(chǎn)生統(tǒng)一的結(jié)果(全部提交或全部回滾)。
X/Open 組織(即現(xiàn)在的 Open Group )定義了分布式事務(wù)處理模型。 X/Open DTP 模型( 1994 )包括應(yīng)用程序( AP )、事務(wù)管理器( TM )、資源管理器( RM )、通信資源管理器( CRM )四部分。一般,常見(jiàn)的事務(wù)管理器( TM )是交易中間件,常見(jiàn)的資源管理器( RM )是數(shù)據(jù)庫(kù),常見(jiàn)的通信資源管理器( CRM )是消息中間件。
通常把一個(gè)數(shù)據(jù)庫(kù)內(nèi)部的事務(wù)處理,如對(duì)多個(gè)表的操作,作為本地事務(wù)看待。數(shù)據(jù)庫(kù)的事務(wù)處理對(duì)象是本地事務(wù),而分布式事務(wù)處理的對(duì)象是全局事務(wù)。
所謂全局事務(wù),是指分布式事務(wù)處理環(huán)境中,多個(gè)數(shù)據(jù)庫(kù)可能需要共同完成一個(gè)工作,這個(gè)工作即是一個(gè)全局事務(wù),例如,一個(gè)事務(wù)中可能更新幾個(gè)不同的數(shù)據(jù)庫(kù)。對(duì)
數(shù)據(jù)庫(kù)的操作發(fā)生在系統(tǒng)的各處但必須全部被提交或回滾。此時(shí)一個(gè)數(shù)據(jù)庫(kù)對(duì)自己內(nèi)部所做操作的提交不僅依賴(lài)本身操作是否成功,還要依賴(lài)與全局事務(wù)相關(guān)的其它
數(shù)據(jù)庫(kù)的操作是否成功,如果任一數(shù)據(jù)庫(kù)的任一操作失敗,則參與此事務(wù)的所有數(shù)據(jù)庫(kù)所做的所有操作都必須回滾。
一般情況下,某一數(shù)據(jù)庫(kù)無(wú)法知道其它數(shù)據(jù)庫(kù)在做什么,因此,在一個(gè) DTP 環(huán)境中,交易中間件是必需的,由它通知和協(xié)調(diào)相關(guān)數(shù)據(jù)庫(kù)的提交或回滾。而一個(gè)數(shù)據(jù)庫(kù)只將其自己所做的操作(可恢復(fù))影射到全局事務(wù)中。
XA 就是 X/Open DTP 定義的交易中間件與數(shù)據(jù)庫(kù)之間的接口規(guī)范(即接口函數(shù)),交易中間件用它來(lái)通知數(shù)據(jù)庫(kù)事務(wù)的開(kāi)始、結(jié)束以及提交、回滾等。 XA 接口函數(shù)由數(shù)據(jù)庫(kù)廠商提供。
XA 與兩階段提交協(xié)議
通常情況下,交易中間件與數(shù)據(jù)庫(kù)通過(guò) XA 接口規(guī)范,使用兩階段提交來(lái)完成一個(gè)全局事務(wù), XA 規(guī)范的基礎(chǔ)是兩階段提交協(xié)議。
在第一階段,交易中間件請(qǐng)求所有相關(guān)數(shù)據(jù)庫(kù)準(zhǔn)備提交(預(yù)提交)各自的事務(wù)分支,以確認(rèn)是否所有相關(guān)數(shù)據(jù)庫(kù)都可以提交各自的事務(wù)分支。當(dāng)某一數(shù)據(jù)庫(kù)收到預(yù)
提交后,如果可以提交屬于自己的事務(wù)分支,則將自己在該事務(wù)分支中所做的操作固定記錄下來(lái),并給交易中間件一個(gè)同意提交的應(yīng)答,此時(shí)數(shù)據(jù)庫(kù)將不能再在該事
務(wù)分支中加入任何操作,但此時(shí)數(shù)據(jù)庫(kù)并沒(méi)有真正提交該事務(wù),數(shù)據(jù)庫(kù)對(duì)共享資源的操作還未釋放(處于上鎖狀態(tài))。如果由于某種原因數(shù)據(jù)庫(kù)無(wú)法提交屬于自己的
事務(wù)分支,它將回滾自己的所有操作,釋放對(duì)共享資源上的鎖,并返回給交易中間件失敗應(yīng)答。在第二階段,交易中間件審查所有數(shù)據(jù)庫(kù)返回的預(yù)提交結(jié)果,如所有數(shù)據(jù)庫(kù)都可以提交,交易中間件將要求所有數(shù)據(jù)庫(kù)做正式提交,這樣該全局事務(wù)被提交。而如果有任一數(shù)據(jù)庫(kù)預(yù)提交返回失敗,交易中間件將要求所有其它數(shù)據(jù)庫(kù)回滾其操作,這樣該全局事務(wù)被回滾。
以一個(gè)全局事務(wù)為例, AP 首先通知交易中間件開(kāi)始一個(gè)全局事務(wù),交易中間件通過(guò) XA 接口函數(shù)通知數(shù)據(jù)庫(kù)開(kāi)始事務(wù),然后 AP 可以對(duì)數(shù)據(jù)庫(kù)管理的資源進(jìn)行操作,數(shù)據(jù)庫(kù)系統(tǒng)記錄事務(wù)對(duì)本地資源的所有操作。操作完成后交易中間件通過(guò) XA 接口函數(shù)通知數(shù)據(jù)庫(kù)操作完成。交易中間件負(fù)責(zé)記錄 AP 操作過(guò)哪些數(shù)據(jù)庫(kù)(事務(wù)分支)。 AP 根據(jù)情況通知交易中間件提交該全局事務(wù),交易中間件會(huì)通過(guò) XA 接口函數(shù)要求各個(gè)數(shù)據(jù)庫(kù)做預(yù)提交,所有數(shù)據(jù)庫(kù)返回成功后要求各個(gè)數(shù)據(jù)庫(kù)做正式提交,此時(shí)一筆全局事務(wù)結(jié)束。
XA 規(guī)范對(duì)應(yīng)用來(lái)說(shuō),最大好處在于事務(wù)的完整性由交易中間件和數(shù)據(jù)庫(kù)通過(guò) XA 接口控制, AP 只需要關(guān)注與數(shù)據(jù)庫(kù)的應(yīng)用邏輯的處理,而無(wú)需過(guò)多關(guān)心事務(wù)的完整性,應(yīng)用設(shè)計(jì)開(kāi)發(fā)會(huì)簡(jiǎn)化很多。
具體來(lái)說(shuō),如果沒(méi)有交易中間件,應(yīng)用系統(tǒng)需要在程序內(nèi)部直接通知數(shù)據(jù)庫(kù)開(kāi)始、結(jié)束和提交事務(wù),當(dāng)出現(xiàn)異常情況時(shí)必須由專(zhuān)門(mén)的程序?qū)?shù)據(jù)庫(kù)進(jìn)行反向操作才能完成回滾。如果是有很多事務(wù)分支的全局事務(wù),回滾時(shí)情況將變得異常復(fù)雜。而使用 XA 接口,則全局事務(wù)的提交是由交易中間件控制,應(yīng)用程序只需通知交易中間件提交或回滾事務(wù),就可以控制整個(gè)事務(wù)(可能涉及多個(gè)異地的數(shù)據(jù)庫(kù))的全部提交或回滾,應(yīng)用程序完全不用考慮沖正邏輯。
在一個(gè)涉及多個(gè)數(shù)據(jù)庫(kù)的全局事務(wù)中,為保證全局事務(wù)的完整性,由交易中間件控制數(shù)據(jù)庫(kù)做兩階段提交是必要的。但典型的兩階段提交,對(duì)數(shù)據(jù)庫(kù)來(lái)說(shuō)事務(wù)從開(kāi)
始到結(jié)束(提交或回滾)時(shí)間相對(duì)較長(zhǎng),在事務(wù)處理期間數(shù)據(jù)庫(kù)使用的資源(如邏輯日志、各種鎖),直到事務(wù)結(jié)束時(shí)才會(huì)釋放。因此,使用典型的兩階段提交相對(duì)
來(lái)說(shuō)會(huì)占用更多的資源,在網(wǎng)絡(luò)條件不是很好,如低速網(wǎng)、網(wǎng)絡(luò)顛簸頻繁,情況會(huì)更為嚴(yán)重。
當(dāng)一個(gè)全局事務(wù)只涉及一個(gè)數(shù)據(jù)庫(kù)時(shí),有一種優(yōu)化方式,即一階段提交。當(dāng) AP 通知交易中間件提交事務(wù)時(shí),交易中間件直接要求數(shù)據(jù)庫(kù)提交事務(wù),省去兩階段提交中的第一階段,可以縮短處理一個(gè)事務(wù)的時(shí)間,以提高事務(wù)處理的效率。作為兩階段提交的一種特例,與兩階段一樣,一階段提交也是標(biāo)準(zhǔn)的。
XA的要求
對(duì)于jms來(lái)說(shuō),需要配置支持XA的 connection factory.
對(duì)于db來(lái)說(shuō),需使用支持XA的JDBC driver.
兩階段提交(2 phase commit)
先說(shuō)transaction的管理,如下圖。

transaction manager與不同的resource manager都有交互。
在phase1時(shí),transaction manager向兩個(gè)resouce詢(xún)問(wèn)是否可以準(zhǔn)備提交。Resouce可回復(fù)ready,
not_ready或是read_only. 當(dāng)兩個(gè)都ready時(shí),則可以進(jìn)入phase2
進(jìn)行提交。任何一個(gè)回復(fù)not_ready則整個(gè)transaction 回滾。回復(fù)read_only的資源在phase2階段被排除在提交過(guò)程之外。

2.JTA
JTA(Java Transaction API) 為 J2EE 平臺(tái)提供了分布式事務(wù)服務(wù)。
要用 JTA 進(jìn)行事務(wù)界定,應(yīng)用程序要調(diào)用 javax.transaction.UserTransaction 接口中的方法。
讓我們來(lái)關(guān)注下面的話(huà):
“用 JTA 界定事務(wù),那么就需要有一個(gè)實(shí)現(xiàn) javax.sql.XADataSource 、
javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC
驅(qū)動(dòng)程序。一個(gè)實(shí)現(xiàn)了這些接口的驅(qū)動(dòng)程序?qū)⒖梢詤⑴c JTA 事務(wù)。一個(gè) XADataSource 對(duì)象就是一個(gè) XAConnection
對(duì)象的工廠。 XAConnection s 是參與 JTA 事務(wù)的 JDBC 連接。”
要使用JTA事務(wù),必須使用XADataSource來(lái)產(chǎn)生數(shù)據(jù)庫(kù)連接,產(chǎn)生的連接為一個(gè)XA連接。
XA連接(javax.sql.XAConnection)和非XA(java.sql.Connection)連接的區(qū)別在于:XA可以參與JTA的事務(wù),而且不支持自動(dòng)提交。
Note:
Oracle, Sybase, DB2, SQL Server,MySQL(5.0以后InnoDB存儲(chǔ)引擎)等大型數(shù)據(jù)庫(kù)才支持XA, 支持分布事務(wù)。
3.OFBiz中實(shí)現(xiàn)的事務(wù)
OFBiz采用Apache Commons DBCP作為數(shù)據(jù)庫(kù)連接池技術(shù),分布式事務(wù)是通過(guò)Apache Geronimo Transaction實(shí)現(xiàn)的。下面是部分實(shí)現(xiàn)類(lèi)關(guān)系:

TransactionFactory和ConnectionFactory都可以自己實(shí)現(xiàn)并且在entityengine.xml中進(jìn)行配置,OFBiz中默認(rèn)配置的是