分布式事務(wù)争涌,如何保證多個系統(tǒng)數(shù)據(jù)的一致性
如果一筆交易涉及到跨多個數(shù)據(jù)庫露该、多個系統(tǒng)的時候,單一的數(shù)據(jù)庫事務(wù)就無法滿足需求了第煮。
那如何解決跨庫數(shù)據(jù)一致性的問題呢解幼?你首先想到肯定是 :分布式事務(wù)
分布式環(huán)境下這事可能就沒這么簡單!
分為分布式環(huán)境,一個交易將會被分在多個不同系統(tǒng)中包警,多個微服務(wù)進程中計算撵摆,在多個數(shù)據(jù)庫中執(zhí)行更新操作。所以并沒有什么分布式事務(wù)或者組件能在分布式環(huán)境下害晦,提供接近單庫事務(wù)一致性的保證特铝。
那么 分布式事務(wù)到底有哪些解決方案呢?
分布式事務(wù)的解決方案有很多壹瘟,比如:2PC鲫剿、3PC、TCC稻轨、Saga 和本地消息表等等灵莲。
2PC:訂單與優(yōu)惠券的數(shù)據(jù)一致性問題
二階段提交,所謂兩階段就是 :準備階段殴俱、提交階段
準備階段:協(xié)調(diào)者分別向訂單系統(tǒng) 優(yōu)惠券系統(tǒng)發(fā)送準備指令政冻,比如開始事務(wù)、插入數(shù)據(jù)最后返回準備成功线欲。
協(xié)調(diào)者根據(jù)收到的 準備成功信息明场,進行下一步的操作。
提交階段就比較簡單了李丰,就是給兩個系統(tǒng)發(fā)送提交指令苦锨。
收到成功后,整個分布式事務(wù)就結(jié)束了趴泌,這是正常的情況舟舒,如果出現(xiàn)了異常了怎么辦?
分兩個階段:
提交階段如果任何一方?jīng)]有正確返回準備成功踱讨,則協(xié)調(diào)者發(fā)送回滾指令魏蔗,準備階段的數(shù)據(jù)進行回滾。
如果進入了提交階段痹筛,這個時候就只能成功莺治。
其實,提交階段因為網(wǎng)絡(luò)服務(wù)等種種原因帚稠,還是有可能失敗谣旁,但是,提交其實是一個快速滋早,輕量級的操作榄审,失敗的概率很小,實際的一致性還是非常好的杆麸。
是不是沒有缺點呢搁进?當然不是:
一是浪感,事務(wù)執(zhí)行的過程會阻塞服務(wù)端的線程和數(shù)據(jù)庫的會話,所以并發(fā)場景性能不會高饼问。
二是影兽,協(xié)調(diào)者一個單點,一旦宕機就會阻塞提交操作莱革。
所以只有在強一致峻堰,并發(fā)量不高的情況下才會考慮使用。
本地消息表:訂單與購物車數(shù)據(jù)的一致性
我們在購物車加入商品后盅视,點擊結(jié)算會進入訂單頁面捐名,這個過程我們做了兩個事情:
一是,清空購物車商品
二是闹击,創(chuàng)建商品訂單
這兩個操作也是要么成功要么失敗镶蹋,但是有一點你 要注意:
購物車商品的清空,不是強一致的呀拇砰,不像 訂單和優(yōu)惠券的的操作梅忌。
晚個幾秒再清空購物車沒什么影響,本地表就非常適合這種分布式最終一致性除破。
思路是這樣的:
當創(chuàng)建訂單的事后牧氮,可以在同一個事務(wù)中記錄一張本地消息表,與訂單在同一個數(shù)據(jù)庫事務(wù)中瑰枫。然后開始一個異步服務(wù)去清空購物車踱葛,如果更新失敗還可以進行重試,直到成功光坝。
使用本地消息表的前提就是尸诽,清空購物車的操作不能依賴其他需要鎖定的資源。