初識Open/X XA

初識Open/X XA

XA是DTP的一部分接口規範。

Distributed Transaction Processing(DTP)

DTP是一種實現分佈式事務處理系統的概念模型,OSI和Open/X組織都有正式文檔來定義它:

  • X/Open Guide, Distributed Transaction Processing Reference Model, X/Open Company Ltd., October 1991.
  • The ISO/IEC Open Systems Interconnection (OSI) Distributed Transaction Processing (DTP) standard.
  • ISO/IEC DIS 10026-1 (1991) (model)
  • ISO/IEC DIS 10026-2 (1991) (service)
  • ISO/IEC DIS 10026-3 (1991) (protocol)

爲了簡化理解,我們只考慮它的靜態結構。在DTP的經典結構圖(下圖)中,整套系統由三種角色構成。

  • 應用程序(Application Program,AP)

    這個角色要做兩件事情,

       一方面是定義構成整個事務所需要的所有操作(就是圖中的2,通過TX接口定義事務邊界)

      另一方面是親自訪問資源節點來執行操作(就是圖中的1)。

The AP defines ** transactions ** and accesses ** resources ** within transaction boundaries.

  • 資源管理器(Resource Managers,RM)

    這個角色是管理着某些共享資源的自治域,比如說一個MySQL數據庫實例。在DTP裏面,還有兩個要求,

一是RM自身必須是支持事務的,

二是RM能夠根據將全局(分佈式)事務標識定位到自己內部的對應事務。

Every RM in the DTP environment must support transactions as described in Section 2.2.1 on page 4
An RM is responsible for mapping its recoverable units of work to the global transaction

  • 事務管理器(Transaction Manager,TM)

    這個角色能與AP和RM直接通信,協調AP和RM來實現分佈式事務的完整性。

主要的工作是

(1)、提供AP註冊全局事務的接口

(2)、頒發全局事務標識(GTID之類 的)

(3)、存儲/管理全局事務的內容

(4)、決策並指揮RM做commit/rollback。

 

XA是RM和TM的交互規範和接口定義,XA 就是 X/Open DTP 定義的交易中間件與數據庫之間的接口規範(即接口函數),交易中間件用它來通知數據庫事務的開始、結束以及提交、回滾等。 XA 接口函數由數據庫廠商提供,大部分數據庫都提供了XA接口實現。

更完整的一張圖如下:

eXtended Architecture(XA)

TM和RM們之間使用的是上文提到的《ISO/TEC DIS 10026-1 (1991) (model)》所定義的二階段提交。

在XA規範的描述中,兩階段提交TM協調RM們完成已定義的全局事務的方法,AP找TM申請/註冊全局事務的動作並不是二階段提交的保障內容。

二階段提交(two-phase commit)

對於單個全局(分佈式)事務,在DTP環境中,二階段提交流程大致如下:

  1. 第一階段(Phase 1)

TM請求所有RM進行準備(prepare commit, or prepare),並告知它們各自需要做的局部事務(transaction branche)。

RM收到請求後,如果判斷可以完成自己的局部事務,那就持久化局部事務的工作內容,再給TM肯定答覆;要是發生了其他情況,那給TM的都是否定答覆。在發送了否定答覆並回滾了局部事務之後,RM才能丟棄持久化了的局部事務信息。

  1. 第二階段(Phase 2)

TM根據情況(比如說所有RM都prepare成功,或者,AP通知它要rollback等),先持久化它對這個全局事務的處理決定和所涉及的RM清單,然後通知所有涉及的RM去提交(commit)或者回滾(rollback)它們的局部事務。

RM們處理完自己的局部事務後,將返回值告訴TM之後,TM纔可以清除掉包括剛纔持久化的處理決定和RM清單在內的這個全局事務的信息。

   

兩階段提交的協議層面優化

  • 只讀斷言

    在Phase 1中,RM可以斷言“我這邊不涉及數據增刪改”來答覆TM的prepare請求,從而讓這個RM脫離當前的全局事務,從而免去了Phase 2。

    這種優化發生在其他RM都完成prepare之前的話,使用了只讀斷言的RM早於AP其他動作(比如說這個RM返回那些只讀數據給AP)前,就釋放了相關數據的上下文(比如讀鎖之類的),這時候其他全局事務或者本地事務就有機會去改變這些數據,結果就是無法保障整個系統的可序列化特性——通俗點說那就會有髒讀的風險。

  • 一階段提交(one-phase commit)

    如果需要增刪改的數據都在同一個RM上,TM可以使用一階段提交——跳過兩階段提交中的Phase 1,直接執行Phase 2。

    但這種優化的本質是跳過Phase 1,這種情況下,RM自行決定了整個局部事務的結果,並且在答覆TM前就清除掉局部事務(因爲Phase 2中RM應答完請求後,TM就沒有必要去聯繫它了),這樣TM就沒有必要去持久化使用了這種優化的全局事務,也導致在某些系統故障(比如說由於網絡通信抖動,TM沒收到RM的回覆)時,TM可能會完全不知道這類事務的執行結果。

使用X/Open XA接口描述的二階段提交

X/Open的XA接口分爲兩類:

  • 一類是ax_開頭的,只有ax_reg()和ax_unreg()兩個,由TM提供給RM調用,從而支撐起RM加入/退出集羣時的動態註冊機制

  • 另一類是xa_開頭的,由RM提供給TM調用,用於實現二階段提交中的各種事務提交、恢復功能

    下面是使用這些接口來描述的二階段提交的一個流程示意圖:

  1. 在開始一個全局事務之前,涉及的RM必須通過ax_regr(),向TM註冊以加入集羣;對應的,在沒有事務需要處理的時候,RM可以通過ax_unreg()向TM要求註銷,離開集羣。

  2. TM在對一個RM執行xa_開頭的具體操作前,必須先通過xa_open()打開這個RM(本質是建立對話)——這其實也是分配XID的一個行爲;與之相應的,TM執行xa_close()來關閉RM。

  3. TM對RM調用的xa_start()和xa_stop()這對組合,一般用於標記局部事務的開頭和結尾。這裏需要注意的有三點:

  4. 對於同一個RM,根據全局事務的要求,可以前後執行多對組合——俾如說,先標記一個流水賬INSERT的局部事務操作,然後再標記賬戶UPDATE的局部事務操作。

  5. TM執行該組合只是起到標記事務的作用,具體的業務命令是由AP交給RM的。

  6. 該組合除了執行這些標記工作外,其實還能在RM中實現多線程的join/suspend/resume管理。

  7. TM調用RM的xa_prepare()來進行第一階段,調用xa_commit()或xa_rollback()執行第二階段。

XA接口清單

規範中使用ISO C描述了一個xa.h的頭文件,給出了XA接口的定義。

  • ax_XXX接口

  • ax_reg
    向一個TM註冊一個RM

  • ax_unreg
    向一個TM註銷一個RM

  • xa_XXX接口

  • xa_close
    停止當前AP對某個RM的使用

  • xa_commit
    通知RM去提交局部事務(第二階段)

  • xa_complete
    詢問指定的異步xa_操作是否完成

  • xa_end
    解除線程與局部事務的關聯

  • xa_forget
    RM存在一種優化方式,就是在第一階段進行先行完成(heuristiccally complete)局部事務,從而儘早釋放資源(如釋放鎖等),但保留局部事務回滾能力與全局事務的對應關係等事務元數據;如果全局事務成功的話,TM通過這個接口許可RM廢棄這個事務的事務元數據

  • xa_open
    初始化某個RM給當前AP使用

  • xa_prepare
    通知目標RM進行第一階段工作

  • xa_recover
    獲取指定RM上已完成了第一階段或者先行完成的XID清單

  • xa_rollback
    通知指定RM回滾指定的局部事務

  • xa_start
    啓動或恢復RM上的局部事務,換句話說,TM告訴這個RM,它後面的工作都與它現在給的XID相關。

參考

Distributed Transaction Processing: The XA Specification

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章