1. 程式人生 > 其它 >分散式事務(三)--XA-2PC-3PC

分散式事務(三)--XA-2PC-3PC

目錄

一、@Transactional存在的問題

1、描述:

Spring的事務只是針對一個數據庫是有效的,當同一個事務中包含的操作使用不同的資料庫,就無法保證ACID特性,這時候就需要分散式事務了。

後面要學習分散式事務的相關內容,XA規範、2PC、3PC、MySQL對XA分散式事務的支援、Spring多資料庫 +
MySQL分散式事務如何實現。

2、最終實現:

把多個數據庫的操作,給包裹在一個事務中,如果任何一個操作報錯,多個數據庫中的操作全部回滾,如果沒有報錯,那麼多個數據庫中的操作全部提交。

二、XA規範:

針對上面的問題,X/Open組織定義了分散式事務的模型,有多個角色。

  1. AP:Application,應用程式,就是我們的系統應用。
  2. TM:Transaction Manager,事務管理器,專門用來管理系統誇資料庫事務的元件。
  3. RM:Resource Manager,資源管理器,就是資料庫MySQL。
  4. CRM:Communication Resource Manager,通訊資源管理器,訊息中介軟體,但也可以不用。

TM:根據XA定義的介面規範,跟每個資料庫進行通訊和互動,通知所有資料庫,要麼一起提交事務,要麼一起回滾。

XA:定義好TM與RM之間的介面規範,就是管理分散式事務的那個元件跟各個資料庫之間通訊的一個介面。
只是一個規範,具體的實現由資料庫產商來提供的,比如說MySQL就會提供XA規範的介面函式和類庫實現,等等。

三、2PC--Two-Phase-Commitment-Protocol

X/Open組織定義的一套分散式事務的理論模型,2PC就是基於XA規範的協議,來讓分散式事務可以落地,定義了實現分散式事務過程中的細節。

1、準備階段:

TM先發送個prepare訊息給各個資料庫,讓各個庫先在本地開個事務,然後執行好SQL,這裡各個資料庫會準備好隨時可以提交或者是回滾,有對應的日誌記錄的。

然後各個資料庫都返回一個響應訊息給事務管理器,如果成功了就傳送一個成功的訊息,如果失敗了就傳送一個失敗的訊息。

2、提交階段:

2.1、第一種情況:

TM收到某個資料庫的返回訊息SQL執行失敗了。或者是TM一直無法收到某個資料庫的返回訊息確認。

直接判定這個分散式事務失敗,然後TM通知所有的資料庫,全部回滾,然後各個庫都回滾好了以後就通知TM,TM就認為整個分散式事務都回滾了。

2.2、第二種情況:

TM接收到所有的資料庫返回的訊息都是成功,直接傳送個訊息通知各個資料庫說提交事務,提交好了通知下TM,TM要是發現所有資料庫的事務都提交成功了,就認為整個分散式事務成功了。

3、2PC存在的問題

3.1、同步阻塞:

執行prepare操作會佔用資源,一直到整個分散式事務完成,才會釋放資源,這個過程中,如果有其他人要訪問這個資源,就會被阻塞住。

3.2、單點故障:

TM是個單點,一旦掛掉就完蛋了。

3.3、事務狀態丟失:

即使把TM做成一個雙機熱備的,一個TM掛了自動選舉其他的TM出來,但是如果TM掛掉的同時,接收到commit訊息的某個庫也掛了。

此時新的TM,壓根兒不知道這個分散式事務當前的狀態,因為不知道哪個庫接收過commit訊息,那個接收過commit訊息的庫也掛了。

3.4、腦裂問題:

如果發生了腦裂問題,那麼就會導致某些資料庫沒有接收到commit訊息,那就完蛋了,有些庫收到了commit訊息,結果有些庫沒有收到。

四、3PC:針對2PC的優化

1、3pc的流程如下:

1.1、CanCommit階段:

TM傳送CanCommit訊息給各個資料庫,然後各個庫返回個結果。
這時不會執行實際的SQL語句的就是各個庫看看自己網路環境是否ready。

1.2、PreCommit階段:

如果各個庫對CanCommit訊息返回的都是成功,就進入PreCommit階段。
TM傳送PreCommit訊息給各個庫,相當於2PC裡的階段一,執行各個SQL語句,只是不提交;
如果有個庫對CanCommit訊息返回了失敗,TM傳送abort訊息給各個庫,結束這個分散式事務。

1.3、DoCommit階段:

如果各個庫對PreCommit階段都返回了成功,那麼傳送DoCommit訊息給各個庫提交事務。
各個庫如果都返回提交成功給TM,那麼分散式事務成功;
如果有個庫對PreCommit返回的是失敗,或者超時一直沒返回,那麼TM認為分散式事務失敗。
直接發abort訊息給各個庫通知回滾,各個庫回滾成功之後通知TM,分散式事務回滾成功。

2、相比2PC的改進點:

2.1、引入了CanCommit階段。

CanCommit階段證明了每個資料庫都是OK的。

2.2、在DoCommit階段,各個庫自己也有超時機制

如果一個庫收到了PreCommit還返回成功了。
超時時間到了,還沒收到TM傳送的DoCommit訊息或者是abort訊息,直接判定為TM可能出故障了,然後自己就執行DoCommit操作提交事務。

3、3PC的缺陷:

TM在DoCommit階段傳送了abort訊息給各個庫,結果因為腦裂問題,某個庫沒接收到abort訊息,其他的庫提交了事務,還是存在問題。

五、全域性事務

針對的是X/Open組織定義了一套分散式事務的模型和規範,DTP(Distributed Transaction Processing
Reference Model),分散式事務處理模型,DTP,TM、RM、AP等等角色的這麼一套分散式事務的模型。

全域性事務,Global Transaction,是DTP模型中的一個概念。指跨多個數據庫的分散式事務。

六、JTA事務

其實是J2EE中的一個概念,Java Transaction API,JTA一套分散式事務的程式設計API,是按照XA、DTP那套模型和規範來搞的,在J2EE中,單庫的事務是通過JDBC事務來支援的。

如果是跨多個庫的事務,是通過JTA API來支援的,通過JTA API可以協調和管理橫跨多個數據庫的分散式事務,一般來說會結合JNDI,J2EE裡面很多東西定義的很好,但是在業內使用的時候,最近這些年基本沒哪個公司用了。