首先,謝謝各位大神的指點。結合工作中遇到的問題和目前我了解到的分布式處理方案來簡單談談。
1.事務的特性
事務必須滿足傳統事務的acid特性,即原子性,一致性,分離性和永續性。
原子性:即最小單位的原子,要不全部成功,要不全部失敗。
永續性:事務完成以後,持久的的儲存在資料庫,不會回滾。
2.本地事務
本地事務,基本都是依賴資料庫,在同乙個資料庫內,用資料庫本身帶的事務來保持事務。操作簡單,這裡就不說了。
3.分布式事務的出現
隨著資料量的增加,單台資料庫,或者簡單的讀寫分離架構已經沒法適應資料量的發展了。這個時候,可能需要做業務的服務化,那靠資料庫本身已經做不了事務了。
定義:分布式事務就是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於不同的分布式系統的不同節點之上.
4.分布式事務解決方案
4.1 兩階段提交協議
xa:xa是乙個分布式事務協議,由tuxedo提出。xa中大致分為兩部分:事務管理器和本地資源管理器。其中本地資源管理器往往由資料庫實現,比如oracle、db2這些商業資料庫都實現了xa介面,而事務管理器作為全域性的排程者,負責各個本地資源的提交和回滾。 總的來說,xa協議比較簡單,而且一旦商業資料庫實現了xa協議,使用分布式事務的成本也比較低。但是,xa也有致命的缺點,那就是效能不理想,特別是在交易下單鏈路,往往併發量很高,xa無法滿足高併發場景。xa目前在商業資料庫支援的比較理想,在mysql資料庫中支援的不太理想,mysql的xa實現,沒有記錄prepare階段日誌,主備切換回導致主庫與備庫資料不一致。許多nosql也沒有支援xa,這讓xa的應用場景變得非常狹隘。
兩階段提交協議:所謂的兩階段提交協議主要是分為2個階段。第一階段:準備階段(投票階段)和第二階段:提交階段(執行階段)
通過以上4步完成了乙個訊息事務。對於以上的4個步驟,每個步驟都可能產生錯誤,下面一一分析:
4.1.1訊息的儲存
如果仔細觀察生活的話,生活的很多場景已經給了我們提示。
比如在北京很有名的姚記炒肝點了炒肝並付了錢後,他們並不會直接把你點的炒肝給你,往往是給你一張小票,然後讓你拿著小票到出貨區排隊去取。
為什麼他們要將付錢和取貨兩個動作分開呢?原因很多,其中乙個很重要的原因是為了使他們接待能力增強(併發量更高)。
還是回到我們的問題,只要這張小票在,你最終是能拿到炒肝的。同理轉賬服務也是如此,當使用者a賬戶扣除1萬後,
我們只要生成乙個憑證(訊息)即可,這個憑證(訊息)上寫著「讓使用者b賬戶增加 1萬」,只要這個憑證(訊息)能可靠儲存,
我們最終是可以拿著這個憑證(訊息)讓使用者b賬戶增加1萬的,即我們能依靠這個憑證(訊息)完成最終一致性。
1)使用者a在扣款事務提交之前,向實時訊息服務請求傳送訊息,實時訊息服務只記錄訊息資料,而不真正傳送,只有訊息傳送成功後才會提交事務;
2)當使用者a扣款事務被提交成功後,向實時訊息服務確認傳送。只有在得到確認傳送指令後,實時訊息服務才真正傳送該訊息;
3)當使用者a扣款事務提交失敗回滾後,向實時訊息服務取消傳送。在得到取消傳送指令後,該訊息將不會被傳送;
4)對於那些未確認的訊息或者取消的訊息,需要有乙個訊息狀態確認系統定時去使用者a系統查詢這個訊息的狀態並進行更新。為什麼需要這一步驟,
舉個例子:假設在第2步使用者a扣款事務被成功提交後,系統掛了,此時訊息狀態並未被更新為「確認傳送」,從而導致訊息不能被傳送。
優點:訊息資料獨立儲存,降低業務系統與訊息系統間的耦合;
缺點:一次訊息傳送需要兩次請求;業務處理服務需要實現訊息狀態回查介面。
4.1.2 重複性提交問題
其實,就是我們說的冪等性問題,即:任意多次執行所產生的影響均與一次執行的影響相同。
分布式事務,本質上是對多個資料庫的事務進行統一控制,按照控制力度可以分為:不控制、部分控制和完全控制。不控制就是不引入分布式事務,部分控制就是各種變種的兩階段提交,包括上面提到的訊息事務+最終一致性、tcc模式,而完全控制就是完全實現兩階段提交。部分控制的好處是併發量和效能很好,缺點是資料一致性減弱了,完全控制則是犧牲了效能,保障了一致性,具體用哪種方式,最終還是取決於業務場景。作為技術人員,一定不能忘了技術是為業務服務的,不要為了技術而技術,針對不同業務進行技術選型也是一種很重要的能力!
延伸閱讀:
springcloud分布式事務處理方案
從github上的starts數量來看,目前還是較多開發者採用了這種方案的,而且作者維護迭代也很及時 將tx manager微服務單獨拎出來,整合在自己的專案中 然後涉及分布式的微服務中新增如下依賴 com.codingapi transaction springcloud org.slf4j co...
分布式補償事務處理方案
事務原子性,一致性,永續性,隔離性是基本的屬性,這裡不解釋,本篇文章只對分布性事務方案做說明方案 隨著分布式微服務應用盛行,帶來的優勢是顯而易見的,但是在面臨事務的時候,缺變的異常麻煩,因為是在不同的應用內,所以無法在單個應用內做回滾處理,這個時候,就需要有乙個單獨的應用做,補償性事務處理。由此引入...
分布式事務處理
前提如下 db a,db b為兩個資料庫 都有乙個person表 該錶兩個字段 personid 主鍵 和personname 下面的分布式事務 實現的是 同時向這兩個庫的兩個表新增資料 set xact abort on 開始分布式事務 begin distributed transaction ...