分佈式事務系列 - 解決跨庫轉帳問題

本文內容

  1. 什麼是分佈式事務
  2. 分佈式事務中的難點
  3. 常見的解決方案
  4. 講解經過可靠消息來解決分佈式事務

什麼是分佈式事務?

有這樣一個需求:數據庫

小明有兩個帳戶,分別位於A、B兩個數據庫中,小明須要將A中的資金轉到B中。微信

咱們如何實現?網絡

按照下面的方式實現看看有沒有問題。併發

  1. 鏈接數據庫A,獲取connA鏈接
  2. connA打開事務
  3. A庫資金減小100
  4. 鏈接庫B,獲取connB鏈接
  5. connB打開事務
  6. B庫資金增長100
  7. connA.commit()
  8. connB.commit()

上面操做,正常狀況是沒有問題。異步

考慮以下狀況:分佈式

第7步執行成功以後,網絡出問題了,第8步會提交失敗,此時的結果是:A庫資金減小了100,B庫資金卻沒有增長;這是一個網絡問題致使了咱們業務失敗了,網絡因素是程序不可控的一些因素,還有其餘的好比運行到7以後,系統忽然斷電了,也會出現一樣的結果。形成了數據錯誤,對業務影響也是比較大的。微服務

分佈式事務能夠這麼理解:一個業務操做中,會包含不少子業務的,每一個子業務都是獨立的事務,咱們須要考慮的是如何保證這些子業務都成功,或者都失敗。blog

分佈式事務中的難點

  1. 分佈式事務中,分支多是各類各樣的,可能存在各類異常狀況致使有些成功有些卻失敗了,這些狀況須要咱們程序可以處理,保證全部的分支要麼都成功、要麼都失敗,不能出現部分紅功而部分失敗的狀況。
  2. 分佈式事務中,很難保證多個分支同時成功。每一個分支可能都是提供遠程接口進行調用,之間存在網絡故障的問題,前面的分支調用成功了,可是其餘分支因爲網絡等不可控的因素而調用不成功,此時數據是很難作到同時一致性的。
  3. 實時一致性難以保證。那麼咱們能夠作到最終一致性也是能夠的。

什麼是最終一致性?

就拿上面的轉帳來講,A庫的資金減小了,因爲網絡問題,操做B庫的connB鏈接斷開了,致使B庫資金沒有增長;網絡問題是能夠恢復了,若是網絡恢復了,系統可以給B中資金加上,這樣最終數據也是正確的;這中間有段時間AB庫的資金是不一致的(A庫減小了100,B庫應該增長100卻沒有增長,數據是不一致的),可是最終某個時間點數據變爲一致了。可以將不一致的時間降到最低是系統須要考慮的問題接口

分佈式事務中,咱們能夠接受數據在某個時間段以內不一致,可是數據最終在某個時間點是一致的。圖片

常看法決方案

  1. 可靠消息模式
  2. TCC模式實現

分佈式事務系列中主要講這2種方案,這兩種方案基本上能夠解決大多數常見的分佈式事務的問題,因此我們必須把這兩種方式拿下。

下面咱們介紹一下使用可靠消息如何實現?

可靠消息模式實現轉帳操做

在這裏插入圖片描述
兩個微服務
服務A:用於操做A庫中的帳戶
服務B:用於操做B庫中的帳戶

兩個服務都是連接獨立的數據庫,依靠數據庫提供的功能,可以保證各自的事務。

對於用戶來講過程以下:

  1. 調用服務A,扣款100
  2. 發送扣款成功的消息到消息服務
  3. 返回用戶轉帳已受理

接着

  1. 服務B,拉取到轉帳消息
  2. B庫中給帳戶+100
  3. 調用消息服務將消息刪除
  4. 服務B消費的過程當中,好比出現網絡、機器重啓等緣由,致使消費失敗,等機器恢復以後,能夠再次消費這條消息,重試屢次最終會成功

上面整個轉帳過程當中有幾點咱們須要考慮一下:

  1. 如何確保A服務中扣款成功以後,消息必定可以發送成功;若是消息發送失敗而丟失了,後面的業務將無法進行。這塊涉及如何發送可靠消息,以前消息系列的文章有介紹,你們能夠看一下:聊聊業務系統中投遞消息到mq的幾種方式
  2. 咱們的服務通常都是集羣的方式,消息消費的時候,可能會出現一條消息併發消費的狀況,併發狀況發生的時候,如何確保消費只可以被消費成功一次。若是一條轉帳消息被成功消費兩次,最終B帳戶中將增長200,致使業務出錯。這塊能夠參考如何保證消息消費的冪等性,這塊以前也有講過,你們也能夠看一下:探討一下實現冪等性的幾種方式

依靠消息模式實現分佈式事物,比較適合消費者必定會處理成功的場景。好比用戶註冊發送郵件、發送短信、送積分等。

總結

  1. 本文主要介紹了什麼是分佈式事務、其中的一些難點
  2. 常見的使用最多的解決方案:異步消息處理分佈式事物、tcc模式
  3. tcc模式咱們在後面的文章中介紹,目前在咱們本身的系統中實現了通用的tcc,已經上線運行,運行也比較穩定
  4. 對分佈式事務有興趣、或有疑問的,能夠加我微信itsoku交流

能夠關注公衆號:路人甲Java,獲取年薪50萬課程,獲取最新文章。

相關文章
相關標籤/搜索