分布式事務怎么控制?
XA是一個分布式事務協議,由Tuxedo提出。XA中大致分為兩部分:事務管理器和本地資源管理器。其中本地資源管理器往往由數據庫實現,比如Oracle、DB2這些商業數據庫都實現了XA接口,而事務管理器作為全局的調度者,負責各個本地資源的提交和回滾。XA實現分布式事務的原理如下:
總的來說,XA協議比較簡單,而且一旦商業數據庫實現了XA協議,使用分布式事務的成本也比較低。但是,XA也有致命的缺點,那就是性能不理想,特別是在交易下單鏈路,往往并發量很高,XA無法滿足高并發場景。XA目前在商業數據庫支持的比較理想,在mysql數據庫中支持的不太理想,mysql的XA實現,沒有記錄prepare階段日志,主備切換回導致主庫與備庫數據不一致。許多nosql也沒有支持XA,這讓XA的應用場景變得非常狹隘。2:非XA方式使用XA方式的效率低,使用消息隊列消除分布式事務又太過復雜,基于效率和時間成本的考慮,我們選用spring的鏈式事務管理器也就是非XA方式 ChainedTransactionManager.他最大努力一階段提交模式中,一個粗糙的事務管理器實現僅僅將一系列其他的事務管理器鏈接在一起,去實現事務的同步,倘若業務處理成功,所有的事務將會提交,否則他們會回滾,最大努力一次提交模式的安全性不如XA事務但是也是相當不錯的,因為能夠承受風險獲得較高的吞吐量收益,如果我們將關鍵業務處理服務設計為一個幕等式(idempotent),這樣發生錯誤的可能性也很小.3:用消息隊列消除分布式事務
所謂的消息事務就是基于消息中間件的兩階段提交,本質上是對消息中間件的一種特殊利用,它是將本地事務和發消息放在了一個分布式事務里,保證要么本地操作成功成功并且對外發消息成功,要么兩者都失敗,開源的RocketMQ就支持這一特性,具體原理如下:1、A系統向消息中間件發送一條預備消息2、消息中間件保存預備消息并返回成功3、A執行本地事務4、A發送提交消息給消息中間件通過以上4步完成了一個消息事務。對于以上的4個步驟,每個步驟都可能產生錯誤,下面一一分析:步驟一出錯,則整個事務失敗,不會執行A的本地操作步驟二出錯,則整個事務失敗,不會執行A的本地操作步驟三出錯,這時候需要回滾預備消息,怎么回滾?答案是A系統實現一個消息中間件的回調接口,消息中間件會去不斷執行回調接口,檢查A事務執行是否執行成功,如果失敗則回滾預備消息步驟四出錯,這時候A的本地事務是成功的,那么消息中間件要回滾A嗎?答案是不需要,其實通過回調接口,消息中間件能夠檢查到A執行成功了,這時候其實不需要A發提交消息了,消息中間件可以自己對消息進行提交,從而完成整個消息事務基于消息中間件的兩階段提交往往用在高并發場景下,將一個分布式事務拆成一個消息事務(A系統的本地操作+發消息)+B系統的本地操作,其中B系統的操作由消息驅動,只要消息事務成功,那么A操作一定成功,消息也一定發出來了,這時候B會收到消息去執行本地操作,如果本地操作失敗,消息會重投,直到B操作成功,這樣就變相地實現了A與B的分布式事務。原理如下:雖然上面的方案能夠完成A和B的操作,但是A和B并不是嚴格一致的,而是最終一致的,我們在這里犧牲了一致性,換來了性能的大幅度提升。當然,這種玩法也是有風險的,如果B一直執行不成功,那么一致性會被破壞,具體要不要玩,還是得看業務能夠承擔多少風險
下一篇三高指哪三高