事務
一個嚴格意義的事務實現(xiàn)纺座,應該具有 4 個屬性:原子性、一致性溉潭、隔離性净响、持久性。這四
個屬性通常稱為 ACID 特性喳瓣。
原子性馋贤,是指一個事務操作不可分割,要么成功畏陕,要么失敗掸掸,不能有一半成功一半失敗的情
況。一致性蹭秋,是指這些數(shù)據(jù)在事務執(zhí)行完成這個時間點之前扰付,讀到的一定是更新前的數(shù)據(jù),之后
讀到的一定是更新后的數(shù)據(jù)仁讨,不應該存在一個時刻羽莺,讓用戶讀到更新過程中的數(shù)據(jù)。隔離性洞豁,是指一個事務的執(zhí)行不能被其他事務干擾盐固。即一個事務內(nèi)部的操作及使用的數(shù)據(jù)對
正在進行的其他事務是隔離的,并發(fā)執(zhí)行的各個事務之間不能互相干擾丈挟,這個有點兒像我們
打網(wǎng)游中的副本刁卜,我們在副本中打的怪和掉的裝備,與其他副本沒有任何關聯(lián)也不會互相影
響曙咽。持久性蛔趴,是指一個事務一旦完成提交,后續(xù)的其他操作和故障都不會對事務的結(jié)果產(chǎn)生任何
影響例朱。
分布式事務
目前大家所說的分布式事務孝情,
更多情況下鱼蝉,是在分布式系統(tǒng)中事務的不完整實現(xiàn)。在不同的應用場景中箫荡,有不同的實現(xiàn)魁亦,
目的都是通過一些妥協(xié)來解決實際問題。
在實際應用中羔挡,比較常見的分布式事務實現(xiàn)有 2PC(Two-phase Commit洁奈,也叫二階段提
交)、TCC(Try-Confirm-Cancel) 和事務消息绞灼。每一種實現(xiàn)都有其特定的使用場景睬魂,也有
各自的問題,都不是完美的解決方案镀赌。
事務消息
- 消息隊列中的“事務”氯哮,主要解決的是消息生產(chǎn)者和消息消費者的數(shù)據(jù)一致性問題。
事務消息適用的場景主要是那些需要異步更新數(shù)據(jù)商佛,并且對數(shù)據(jù)實時性要求不太高的場景喉钢。
一個小例子:
消息隊列是實現(xiàn)分布式事務
- 訂單系統(tǒng)在消息隊列上開啟一個事務。
- 訂單系統(tǒng)給消息服務器發(fā)送一個“半消
息”良姆,這個半消息不是說消息內(nèi)容不完整肠虽,它包含的內(nèi)容就是完整的消息內(nèi)容,半消息和普
通消息的唯一區(qū)別是玛追,在事務提交之前税课,對于消費者來說,這個消息是不可見的痊剖。 - 半消息發(fā)送成功后韩玩,訂單系統(tǒng)就可以執(zhí)行本地事務了,在訂單庫中創(chuàng)建一條訂單記錄陆馁,并提
交訂單庫的數(shù)據(jù)庫事務找颓。 - 根據(jù)本地事務的執(zhí)行結(jié)果決定提交或者回滾事務消息。
(1)如果訂單創(chuàng)建成功:
那就提交事務消息叮贩,購物車系統(tǒng)就可以消費到這條消息繼續(xù)后續(xù)的流程击狮。
(2)如果訂單創(chuàng)建失敗,那就回滾事務消息益老,購物車系統(tǒng)就不會收到這條消息彪蓬。
處理事務消息提交失敗 -- RocketMQ事務反查機制
在 RocketMQ 中的事務實現(xiàn)中,增加了事務反查的機制來解決事務消息提交失敗的問題捺萌。
如果 Producer 也就是訂單系統(tǒng)档冬,在提交或者回滾事務消息時發(fā)生網(wǎng)絡異常,RocketMQ
的 Broker 沒有收到提交或者回滾的請求,Broker 會定期去 Producer 上反查這個事務對
應的本地事務的狀態(tài)捣郊,然后根據(jù)反查結(jié)果決定提交或者回滾這個事務。
為了支撐這個事務反查機制慈参,我們的業(yè)務代碼需要實現(xiàn)一個反查本地事務狀態(tài)的接口呛牲,告知
RocketMQ 本地事務是成功還是失敗。
在我們這個例子中驮配,反查本地事務的邏輯也很簡單娘扩,我們只要根據(jù)消息中的訂單 ID,在訂
單庫中查詢這個訂單是否存在即可壮锻,如果訂單存在則返回成功琐旁,否則返回失敗。
RocketMQ 會自動根據(jù)事務反查的結(jié)果提交或者回滾事務消息猜绣。
這個反查本地事務的實現(xiàn)灰殴,并不依賴消息的發(fā)送方,也就是訂單服務的某個實例節(jié)點上的任
何數(shù)據(jù)掰邢。這種情況下牺陶,即使是發(fā)送事務消息的那個訂單服務節(jié)點宕機了,RocketMQ 依然
可以通過其他訂單服務的節(jié)點來執(zhí)行反查辣之,確保事務的完整性掰伸。