步驟1-2是在本地事務執行之前,服務a負責生成乙個全域性唯一的事務id,並在訊息管理服務上註冊乙個訊息。這一步如果失敗,整個事務被判定失敗,不會出現資料不一致問題。這兩個步驟主要是為了容錯,後續當步驟4如果沒有執行,訊息管理服務會定時撈出未提交的事務,反查服務a的介面,確認事務是提交還是取消。提交則繼續往下傳遞,取消則判定當前事務失敗。
步驟3是執行本地事務。這一步如果失敗,事務判定失敗,繼續呼叫步驟4取消事務。
步驟4是提交/取消事務,告訴訊息管理服務,訊息是否可以繼續往下傳播。這一步如果失敗,會有步驟1中所說的反查的操作進行補償。
步驟5是訊息繼續往下乙個節點傳遞。如果訊息沒有被ack,會定時重發。因此下游節點需要實現冪等。
步驟6是服務b執行本地事務。
步驟7用於確認服務b的事務也執行完畢。如果沒有執行,步驟5會重發直到得到反饋。如果步驟6一直沒有成功,在多次重試後需要人工介入。
整個方案的流程基本都是基於二次確認和訊息的重試來完成,比較好理解,唯獨」反查「這一步需要說明一下。
很多mq的client sdk中都提供了乙個反查介面,使用者只需要實現這個介面即可。
但是如果每個接入分布式事務的方法都需要實現乙個介面,讓訊息管理服務來反查步驟3的本地事務是否成功,那工作量是不可接受的。
我們首先介紹一種在業務層實現的方式,先看一下常見的spring框架下事務的執行方式:
@messagetransaction註解,主要是為了讓clent sdk中的自定義aop切面可以通過掃瞄該註解,確定要執行事務的方法,並確保與業務方法在同乙個spring事務中。
當業務在處理本地事務時,我們的自定義aop會隱式往訊息事務的表中插入一條資料。注意要通過@order調整aop順序,確保clent sdk的aop插入操作和業務在同乙個spring事務裡。由於往事務表中插入資料的操作是自定義註解aop隱式實現的,因此對開發者無感。
至於反查的通訊方式,可以通過tcp長連線通訊,或者client sdk自帶http服務埠等方式。
另外一種方式,我們可以在資料來源層實現隱式資料插入操作,但這就需要我們對sql的解析等操作,這在一些分布式事務框架中已經實現。當然,實現方式有很多,本文只是列出其中一種比較簡單的思路。
這次我們介紹了基於訊息的事務方案,在後面的文章中,我們會繼續介紹其他分布式事務框架的具體方案。
分布式事務(二)分布式事務方案
首先這是普通事務 下面是分布式事務 在微服務系統中,每個微服務應用都可能會有自己的資料庫,它們首先需要控制自己的本地事務。一項業務操作可能會呼叫執行多個微服務。如何保證多個服務執行的多個資料庫的操作整體成功或整體失敗?這就是分布式事務要解決的問題。cap 和 base 是對大規模網際網路系統分布式實...
事務 分布式事務解決方案
事務acid特性 事務隔離級別 指的是讀和寫同時出現時出現的資料不一致問題。事務的一致性問題 存在問題問題描述 髒讀 dirty read 針對的是單條資料。即乙個更新操作a修改了某一條資料,但尚未提交該事務,此時另乙個讀操作b來查詢該條資料,讀到的是修改後的但尚未提交的資料。不可重複讀 unrep...
事務 分布式事務
事務 邏輯上的一組操作,要麼都成功要麼都失敗 事務的四個特性 acid 原子性,一致性,隔離性,永續性 事務的隔離級別 讀未提交 產生髒讀 讀已提交 不可重複讀 可重複讀 幻讀 mysql預設 序列化讀 效能最低 傳播行為 7個 七種傳播行為 required 支援當前事務,如果不存在,就新建乙個 ...