簡介
有關在中間件環境中配置和使用 XA 的一篇早期文章 中提到,Open Group 的 X/Open Distributed Transaction Processing(DTP)模型中發布的 XA 標准定義了事物管理器、應用程序和資源管理器之間的接口,以在 DTP 環境中實現兩階段提交:
應用程序執行所期望的業務功能。它指定了一系列包含了資源(如數據庫)的操作。應用程序對全局事務的開始和結束進行了定義,在事務界限內獲取資源,並且通常決定是否提交或回滾每個事務。
事務管理器管理全局事務,並協調進行提交或回滾的決定,從而確保它們的原子性。在需要時(如一個組件出故障後),事務管理器還可以協調資源管理器的恢復活動。
資源管理器管理計算機的部分共享資源。許多其他軟件實體使用資源管理器提供的服務,不時地請求訪問資源。一些資源管理器管理一個通信資源。
在一個分布式、包含了遵從 XA 的資源管理器的事務環境中,應用程序尤其需要認識事物處理,這是因為有些額外的考慮因素必須包含到在這個環境中運行的應用程序中。如果資源管理器出了故障,應用程序必須知道事務管理器是如何運作的,並使用特殊的邏輯進行彌補,以應對此類故障。事務管理器要能夠處理某些資源管理器的故障,而且發生這種情況時,事務管理器還要能夠繼續操作,這點也很重要。這一點有助於確保事務管理器的有效性,並且在一定程度上幫助簡化應用程序邏輯。作為一名程序員,除了應用程序以外,您應該測試在此類環境中事務管理器的行為,這樣您才能確保充分支持所需的任何特別處理。
本文展示了當資源管理器出故障時,預期的事務管理器行為。以下部分將討論常見的故障場景、對應的 XA 錯誤、當相關資源管理器出故障時事務管理器的行為,以及在這些場景下,有助於事務管理器獲得更高可用性的考慮因素。
資源管理器故障的常見原因
一些常見的原因會引起資源管理器故障或變得不可用,其中包括:
資源管理器端運行時不一致將導致事務故障。
資源管理器存儲故障將導致資源管理器崩潰。
暫時或長期的網絡故障將導致資源管理器不可用。
一個資源管理器會返回兩個主要的 “災難性的” XA 錯誤:
XAER_RMERR:這個錯誤表示在事務分支中,某個資源管理器出錯了。導致這種錯誤可能有幾種情況。例如,資源管理器認為它絕不會提交分支,無法支持處於准備狀態的分支資源,或者從控制線程中分離事務分支時出現錯誤。
XAER_RMFAIL:這個錯誤表示出現了普通錯誤,導致資源管理器不可用。
涉及到的資源管理器在執行過程中的不同時間點都可能會出現故障。進行一個 XA 相關的請求時,事務管理器通常會檢測故障。下面是一些示例案例以及相應的事務管理器的期望行為:
使用 A_OPEN 建立連接的同時,執行事務的進程檢測到一個錯誤。
期望的行為:如果 XA_OPEN 出錯,事務管理器要發出警告,並且繼續正常運行。事務管理器不能處理指向不可用資源管理器的事務。而且不能有任何 XA 相關的流指向不可用的資源管理器。
啟動事務前,事務管理器檢測到一個錯誤。
期望的行為:如果流中的任何請求(如 XA_START、XA_END、XA_PREPARE等等)出現錯誤,那麼事務也將出錯。任何 XA 流都不應指向不可用的資源管理器。
在准備和提交進程期間,資源管理器出現故障,事務管理器檢測到錯誤。
期望的行為:如果故障出現在提交進程完成之前,那麼事務的行為將無法確定。當資源管理器再次恢復可用時,事務管理器需要能夠完成事務。將由事務管理器的實現器決定執行線程是否繼續重新提交請求或保持阻止狀態。
您的事務管理器能保證較高的可用性嗎?
下面是一些考慮因素,您可以用來考慮事務管理器,確保即使發生了災難性的 XA 故障(如在一個分布的 XA 事務過程中,資源管理器不可用)的情況下,它還能保持高度可用:
從出故障到資源管理器恢復可用之前,您還能夠使用事務管理器運行非 XA 事務嗎?
您能夠運行未涉及出故障的資源管理器的事務嗎?
即使在發生故障的資源管理器持續不可用時,您能夠在事務管理器中提交下一個事務而不出現問題嗎?
資源管理器恢復可用時,包含了出故障的資源管理器的事務是否也自動解決了問題呢?
資源管理器恢復可用前,事務管理器的行為是什麼?執行需要恢復的事務的線程或進程是否不斷重試資源管理器,希望它恢復可用?
事務管理器是否存有舊連接?資源管理器恢復可用後,新事務的第一次調用是否會出錯?
當資源管理器在不同時間點出現故障時,下面小節展示的一些測試案例可以幫助您解決這些問題,因為它們都與事務管理器相關。如果這些條件都不符合您的情況,應該與供貨商商議事務管理器的功能。
面向 XA 彈性的測試案例
如果一個資源管理器失效,下面的四個測試案例能夠幫您判斷事務管理器是否能夠在高可用性的情況下運行。所有的測試案例都有著同樣的假設:
事務管理器要麼是一個多線程環境,要麼是一個多進程環境。如果是多線程環境,執行事務的單元就是一個線程(叫做執行線程或 ToE)。如果是多進程環境,執行事務的單元就是一個進程(叫作一個執行進程或 PoE)。
這些測試案例演示一個多進程事務管理器,因此每個事務都是在一個獨立的進程中執行的。然而,即使執行單元是一個線程,期望的事務管理器行為都是相同的。目的是要說明只有執行事務的進程或線程受到了影響,而總的事務管理器不受影響,並且可用於其它類型的任務。
IBM® DB2® 將被作為資源管理器的一個示例在此使用,在測試過程的不同階段,狀態將發生變化(可用或不可用)。事務管理器的行為應該不會受到資源管理器狀態變化的影響。
在實驗室測試過程中,應該使用 dbx 之類的調試器(在 AIX® 上)在某個點強行停止或啟用 PoE。進行這些測試時,您可以使用自己選擇的工具或方法。
案例 1:執行事務時,資源管理器出故障
情景:在執行使用資源管理器的事務時,資源管理器不可用。請參見圖 1。
測試:
事務管理器在運行並且可用。
事務管理中的一個進程執行一個 DB2 相關的事務。
在執行事務期間,關閉 DB2。
事務發出一個提交或回滾(xa_commit 從進程中流出)。
由於 DB2 不可用,事務(以及進程)遇到一個 xa_error(XAER_RMERR)。
執行事務的進程用其所期望的方式處理錯誤(例如,重啟執行事務的進程)。
檢測行為:
確保事務管理器總體上保持可用,即使進程檢測到了故障,也只有執行事務的那個進程受到影響。
一旦發生了如 XAER_RMERR 之類的故障,如果事務管理器的行為是要重啟進程,那麼檢測重啟的執行進程(圖 1 中的 PoE(1))是否在重試,直到出錯的事務恢復為止。出錯的資源管理器恢復可用時,事務也將恢復。只有在出故障的事務需要恢復時才需要執行這個檢測。
在特定的 DB2 實例恢復可用之前,包含了出錯的 DB2 實例的其他事務可能會出現故障。
即使出錯的 DB2 實例持續不可用,沒有包含 DB2 的事務應該能夠繼續正常運行。
啟用 DB2,使其可用。
所有重新提交的事務應該能夠再次正常運行。
這個測試有助於驗證 問題 c、d 和 e。
圖 1. 案例 1
圖片看不清楚?請點擊這裡查看原圖(大圖)。
案例 2:連接到一個進程時,資源管理器出現故障
情景:執行進程連接到資源管理器。資源管理器崩潰。提交一個包含了出錯的資源管理器的事務。請參見圖 2。
測試:
事務管理器正在運行中而且可用。
執行事務的進程連接到了 DB2。沒有事務在運行。
關閉 DB2。
運行一個沒有包含 DB2 的事務。事務應該正常執行。
運行一個包含了 DB2 的事務。事務應該會失敗,並且出現一個 SQL 錯誤。
PoE 應該處理錯誤,並采取相應動作。
檢測行為:
事務管理器總體上要保持可用。
啟用 DB2。
激活一個包含了 DB2 的事務。新的事務開始運行時,發出 XA_OPEN,並建立一個連接。事務應該正常執行。
這個測試有助於驗證 問題 a。
圖 2. 案例 2
圖片看不清楚?請點擊這裡查看原圖(大圖)。
案例 3:資源管理器出現故障後,進程保持舊的處理
這個測試有助於驗證 問題 c、d 和 e。
圖 1. 案例 1
圖片看不清楚?請點擊這裡查看原圖(大圖)。
案例 2:連接到一個進程時,資源管理器出現故障
情景:執行進程連接到資源管理器。資源管理器崩潰。提交一個包含了出錯的資源管理器的事務。請參見圖 2。
測試:
事務管理器正在運行中而且可用。
執行事務的進程連接到了 DB2。沒有事務在運行。
關閉 DB2。
運行一個沒有包含 DB2 的事務。事務應該正常執行。
運行一個包含了 DB2 的事務。事務應該會失敗,並且出現一個 SQL 錯誤。
PoE 應該處理錯誤,並采取相應動作。
檢測行為:
事務管理器總體上要保持可用。
啟用 DB2。
激活一個包含了 DB2 的事務。新的事務開始運行時,發出 XA_OPEN,並建立一個連接。事務應該正常執行。
這個測試有助於驗證 問題 a。
圖 2. 案例 2
圖片看不清楚?請點擊這裡查看原圖(大圖)。
案例 3:資源管理器出現故障後,進程保持舊的處理
情景:資源管理器崩潰。恢復可用後,提交一個涉及到資源管理器的事務。請參見圖 3。
測試:
事務管理器正在運行。
執行事務的進程使用 XA_OPEN 連接到 DB2。
關閉 DB2。
沒有包含 DB2 的事務應該在正常運行。
啟用 DB2。
提交一個包含了 DB2 的事務。檢查應用程序是否由於 PoE 中的一些舊連接導致了連接錯誤。
檢查行為:
在一些事務管理器中,由於舊的處理導致錯誤後,PoE 會進行重啟,然後建立一個新的連接,並且重新提交事務。這意味著為了去除舊的連接處理,PoE 需要進行循環運行。
這有助於驗證 問題 f。
圖 3. 案例 3
圖片看不清楚?請點擊這裡查看原圖(大圖)。
案例 4:使用不可用的資源管理器啟動進程和提交事務。
情景:資源管理器不可用時,啟動一個 PoE。資源管理器不可用時,提交一個事務。請參見圖 4。
測試:
事務管理器可用。
DB2 不可用。
啟動一個新的 PoE。XA_OPEN 失敗。
提交一個包含了指向 DB2 的 SQL 語句的事務。DB2 不可用時,會遇到 SQL 錯誤。沒有 ax_reg 在流動(在動態注冊的情況下)。由於沒有對不可用的 DB2 發出 XA 請求,回滾應該會正確運行(這個特定的 DB2 還沒有被作為參與的 XA 資源管理器進行注冊)。
檢測行為:
事務處理器總體上要保持可用。
非 SQL 事務(和沒有包含 DB2 的事務)應該能繼續正常運行。
啟用 DB2。
提交一個包含了 DB2 的事務。用 DB2 建立連接,並且事務應該成功運行。
這個測試有助於驗證 問題 b。
圖 4. 案例 4
圖片看不清楚?請點擊這裡查看原圖(大圖)。
保護您的事務管理器,防止其受到資源管理器影響
下面是一些設計考慮因素,可以使您的事務管理器靈活應對資源管理器故障:
確保將不可用的資源管理器標記為對事務管理器不可用,並且事務管理器能夠繼續與其他的資源管理器一起運行。
事務管理器應該能夠繼續處理沒有包含出錯資源管理器的事務。
即使參與事務的一個資源管理器發生了災難性的錯誤,事務管理器應該仍然可用。
事務管理器應該在資源管理器可用時,能夠檢測到其可用性。
事務管理器應該能夠在出錯的資源管理器恢復可用時解決出錯的事務。
事務管理器應該能夠在出錯的資源管理器可用時,繼續運行包含了出錯的資源管理器的新事務請求。
要把舊的連接從事務管理器的緩存中移除,這樣的話,資源管理器恢復可用後的第一個事務調用就不會出錯。
最後,介紹一些小訣竅,可以幫助您使用一些流行的資源管理器:
對於 IBM WebSphere® MQ 來說,只有發布了具有同步點選項的 MQPUT,ax_reg 才會流向事務管理器。這意味著如果把 WebSphere MQ 設置為動態注冊,而且錯誤出現在具有同步點的 MQPUT 之前,WebSphere MQ 可能就不支持 XA 彈性功能。
使用除 DB2 以外的一些流行的資源管理器時,如果在 xa_end 的過程中出錯,將會返回 XAERR_PROTO,而不是 XAERR_RMERR。事務管理器要能夠容忍不同資源管理器在發生類似錯誤時返回的不同錯誤代碼而導致的不同行為。
結束語
在當今的企業中,如果核心系統的可用性非常關鍵的話,那麼諸如事務管理器之類的核心組件在其他相關組件出錯時還能保持可用性,這點非常重要。本文中的測試案例能夠幫助您提前判斷企業系統中的事務管理器是否對某些類型的錯誤具有靈活的應變能力。