分布式事務(wù)

什么是事務(wù)戏罢?

發(fā)生錯誤屋谭,回滾操作。
要么全部正確執(zhí)行帖汞,要么全不執(zhí)行。

事務(wù)四大特性

ACID 原子性Atomicity凑术,一致性Consistency翩蘸,隔離性Isolation,持久性Durability

  • 原子性:事務(wù)里是一個不可分割整體淮逊,要么一起執(zhí)行催首,要么一起不執(zhí)行。
  • 一致性:事務(wù)執(zhí)行前后泄鹏,數(shù)據(jù)庫一致性沒有被破壞郎任。提交事務(wù)沒有中間狀態(tài)。要么提交前备籽,要么提交后舶治。
  • 隔離性:事務(wù)之間互不干擾。
  • 持久性:提交了就永久改變了车猬,不會不生效霉猛。

事務(wù)隔離級別


讀未提交 read-uncommitted
  • A還沒提交,B就讀了珠闰。若A rollback惜浅,B讀到錯誤數(shù)據(jù)(臟讀)。
不可重復(fù)讀/讀提交 read-committed
  • 提交了才能讀
  • A讀伏嗜,B修改并提交坛悉,A再讀變了(不可重復(fù)讀)
可重復(fù)讀 repeatable-read
  • 讀時不可修改(行鎖)A讀伐厌,B不準(zhǔn)改,A再讀完成裸影,B改
  • A讀(范圍)挣轨,B插入并提交(不修改A鎖的),A再讀空民,個數(shù)變了(幻讀)
串行化/可 serializable
  • 讀時不可增刪改(表鎖)
事務(wù)隔離級別 臟讀 不可重復(fù)讀 幻讀
讀未提交(read-uncommitted) ? ? ?
不可重復(fù)讀(read-committed) ? ? ?
可重復(fù)讀(repeatable-read) ? ? ?
串行化(serializable) ? ? ?

級別越高刃唐,執(zhí)行效率就越低。

  • MySQL默認(rèn)可重復(fù)讀界轩。
  • Oracle默認(rèn)讀提交画饥,支持read committed 和 serializable。另外還支持read only(只讀浊猾,不可修改) 和 read write(默認(rèn))

事務(wù)傳播級別

7種:

傳播級別 描述 上下文存在事務(wù) 上下文不存在事務(wù)
REQUIRED 默認(rèn) 加入事務(wù)中 新建事務(wù)
SUPPORTS 支持 加入事務(wù)中 非事務(wù)方式執(zhí)行
MANDATORY 強制上下文有事務(wù) 加入事務(wù) 拋出異常
REQUIRES_NEW 新事務(wù) 新建事務(wù)抖甘,掛起上下文事務(wù) 新建事務(wù)
NOT_SUPPORTED 不支持 掛起上下文事務(wù),執(zhí)行當(dāng)前邏輯 新建事務(wù)
NEVER 不可有上下文事務(wù) 拋出runtime異常,強制停止 非事務(wù)方式執(zhí)行
NESTED 嵌套執(zhí)行 子回滾,父不影響缰冤;父回滾俏扩,子回滾;子先提交陶因,父后提交 新建事務(wù)

一致性解決方案

兩階段提交(2PC),三階段提交(3PC),補償事務(wù)(TCC)柄沮,消息中間件(MQ異步確保)& 最大努力通知(定期校對)

兩階段提交(2PC)

Prepare、Commit 兩個階段

準(zhǔn)備階段

1)協(xié)調(diào)者節(jié)點向所有參與者節(jié)點詢問是否可以執(zhí)行提交操作(vote)废岂,并開始等待各參與者節(jié)點的響應(yīng)祖搓。
2)參與者節(jié)點執(zhí)行詢問發(fā)起為止的所有事務(wù)操作,并將Undo信息和Redo信息寫入日志湖苞。(注意:若成功這里其實每個參與者已經(jīng)執(zhí)行了事務(wù)操作)
3)各參與者節(jié)點響應(yīng)協(xié)調(diào)者節(jié)點發(fā)起的詢問拯欧。如果參與者節(jié)點的事務(wù)操作實際執(zhí)行成功,則它返
回一個”同意”消息财骨;如果參與者節(jié)點的事務(wù)操作實際執(zhí)行失敗镐作,則它返回一個”中止”消息。

提交階段
  • 當(dāng)協(xié)調(diào)者節(jié)點從所有參與者節(jié)點獲得的相應(yīng)消息都為”同意”時:
    1)協(xié)調(diào)者節(jié)點向所有參與者節(jié)點發(fā)出”正式提交(commit)”的請求隆箩。
    2)參與者節(jié)點正式完成操作滑肉,并釋放在整個事務(wù)期間內(nèi)占用的資源。
    3)參與者節(jié)點向協(xié)調(diào)者節(jié)點發(fā)送”完成”消息摘仅。
    4)協(xié)調(diào)者節(jié)點受到所有參與者節(jié)點反饋的”完成”消息后靶庙,完成事務(wù)。

  • 如果任一參與者節(jié)點在第一階段返回的響應(yīng)消息為”中止”,或者 協(xié)調(diào)者節(jié)點在第一階段的詢問超時之前無法獲取所有參與者節(jié)點的響應(yīng)消息時:
    1)協(xié)調(diào)者節(jié)點向所有參與者節(jié)點發(fā)出”回滾操作(rollback)”的請求六荒。
    2)參與者節(jié)點利用之前寫入的Undo信息執(zhí)行回滾护姆,并釋放在整個事務(wù)期間內(nèi)占用的資源。
    3)參與者節(jié)點向協(xié)調(diào)者節(jié)點發(fā)送”回滾完成”消息掏击。
    4)協(xié)調(diào)者節(jié)點受到所有參與者節(jié)點反饋的”回滾完成”消息后卵皂,取消事務(wù)。

2PC缺點:
  1. 同步阻塞問題砚亭。執(zhí)行過程中灯变,所有參與節(jié)點都是事務(wù)阻塞型的。當(dāng)參與者占有公共資源時捅膘,其他第三方節(jié)點訪問公共資源不得不處于阻塞狀態(tài)添祸。
  2. 單點故障。由于協(xié)調(diào)者的重要性寻仗,一旦協(xié)調(diào)者發(fā)生故障刃泌。參與者會一直阻塞下去。尤其在第二階段署尤,協(xié)調(diào)者發(fā)生故障耙替,那么所有的參與者還都處于鎖定事務(wù)資源的狀態(tài)中,而無法繼續(xù)完成事務(wù)操作曹体。(如果是協(xié)調(diào)者掛掉俗扇,可以重新選舉一個協(xié)調(diào)者,但是無法解決因為協(xié)調(diào)者宕機導(dǎo)致的參與者處于阻塞狀態(tài)的問題)
  3. 數(shù)據(jù)不一致箕别。在二階段提交的階段二中铜幽,當(dāng)協(xié)調(diào)者向參與者發(fā)送commit請求之后,發(fā)生了局部網(wǎng)絡(luò)異尘吭校或者在發(fā)送commit請求過程中協(xié)調(diào)者發(fā)生了故障啥酱,這回導(dǎo)致只有一部分參與者接受到了commit請求爹凹。而在這部分參與者接到commit請求之后就會執(zhí)行commit操作厨诸。但是其他部分未接到commit請求的機器則無法執(zhí)行事務(wù)提交。于是整個分布式系統(tǒng)便出現(xiàn)了數(shù)據(jù)部一致性的現(xiàn)象禾酱。
  4. 二階段無法解決的問題:協(xié)調(diào)者再發(fā)出commit消息之后宕機微酬,而唯一接收到這條消息的參與者同時也宕機了。那么即使協(xié)調(diào)者通過選舉協(xié)議產(chǎn)生了新的協(xié)調(diào)者颤陶,這條事務(wù)的狀態(tài)也是不確定的颗管,沒人知道事務(wù)是否被已經(jīng)提交。

三階段提交(3PC)

CanCommit滓走、PreCommit垦江、DoCommit三個階段

  1. 引入超時機制。同時在協(xié)調(diào)者和參與者中都引入超時機制搅方。
  2. 在第一階段和第二階段中插入一個準(zhǔn)備階段比吭。保證了在最后提交階段之前各參與節(jié)點的狀態(tài)是一致的绽族。
CanCommit階段

協(xié)調(diào)者向參與者發(fā)送commit請求,參與者如果可以提交就返回Yes響應(yīng)衩藤,否則返回No響應(yīng)吧慢。

  1. 事務(wù)詢問 協(xié)調(diào)者向參與者發(fā)送CanCommit請求。詢問是否可以執(zhí)行事務(wù)提交操作赏表。然后開始等待參與者的響應(yīng)检诗。

  2. 響應(yīng)反饋 參與者接到CanCommit請求之后,正常情況下瓢剿,如果其自身認(rèn)為可以順利執(zhí)行事務(wù)逢慌,則返回Yes響應(yīng),并進(jìn)入預(yù)備狀態(tài)跋选。否則反饋No

PreCommit階段
  • 假如協(xié)調(diào)者從所有的參與者獲得的反饋都是Yes響應(yīng)涕癣,那么就會執(zhí)行事務(wù)的預(yù)執(zhí)行。
  1. 發(fā)送預(yù)提交請求 協(xié)調(diào)者向參與者發(fā)送PreCommit請求前标,并進(jìn)入Prepared階段坠韩。
  2. 事務(wù)預(yù)提交 參與者接收到PreCommit請求后,會執(zhí)行事務(wù)操作炼列,并將undo和redo信息記錄到事務(wù)日志中只搁。
  3. 響應(yīng)反饋 如果參與者成功的執(zhí)行了事務(wù)操作,則返回ACK響應(yīng)俭尖,同時開始等待最終指令氢惋。
  • 假如有任何一個參與者向協(xié)調(diào)者發(fā)送了No響應(yīng),或者等待超時之后稽犁,協(xié)調(diào)者都沒有接到參與者的響應(yīng)焰望,那么就執(zhí)行事務(wù)的中斷。
  1. 發(fā)送中斷請求 協(xié)調(diào)者向所有參與者發(fā)送abort請求已亥。
  2. 中斷事務(wù) 參與者收到來自協(xié)調(diào)者的abort請求之后(或超時之后熊赖,仍未收到協(xié)調(diào)者的請求),執(zhí)行事務(wù)的中斷虑椎。

相對于2PC震鹉,3PC主要解決的單點故障問題,并減少阻塞捆姜,因為一旦參與者無法及時收到來自協(xié)調(diào)者的信息之后传趾,他會默認(rèn)執(zhí)行commit。而不會一直持有事務(wù)資源并處于阻塞狀態(tài)泥技。但是這種機制也會導(dǎo)致數(shù)據(jù)一致性問題浆兰,因為,由于網(wǎng)絡(luò)原因,協(xié)調(diào)者發(fā)送的abort響應(yīng)沒有及時被參與者接收到簸呈,那么參與者在等待超時之后執(zhí)行了commit操作宽涌。這樣就和其他接到abort命令并執(zhí)行回滾的參與者之間存在數(shù)據(jù)不一致的情況。


補償事務(wù)(TCC)

基于業(yè)務(wù)層面的事務(wù)定義蝶棋。
鎖粒度完全由業(yè)務(wù)自己控制卸亮。
本質(zhì)是一種補償?shù)乃悸贰?br> 把事務(wù)運行過程分成 Try、Confirm / Cancel 兩個階段

Try :嘗試執(zhí)行業(yè)務(wù)
  • 完成所有業(yè)務(wù)檢查( 一致性 )
  • 預(yù)留必須業(yè)務(wù)資源( 準(zhǔn)隔離性 )
Confirm / Cancel 階段:
  • Confirm :
    真正執(zhí)行業(yè)務(wù)
    不做任務(wù)業(yè)務(wù)檢查
    Confirm 操作滿足冪等性
  • Cancel :
    釋放 Try 階段預(yù)留的業(yè)務(wù)資源
    Cancel 操作滿足冪等性
    Confirm 與 Cancel 互斥

本地消息表

將需要分布式處理的任務(wù)通過消息日志的方式來異步執(zhí)行玩裙。消息日志可以存儲到本地文本兼贸、數(shù)據(jù)庫或消息隊列,再通過業(yè)務(wù)規(guī)則自動或人工發(fā)起重試吃溅。
本地消息表記錄狀態(tài)溶诞,定時掃描,重新發(fā)送失敗的消息


消息中間件(MQ異步確保) 最大努力通知(定期校對)

RocketMQ

  • 業(yè)務(wù)方法內(nèi)要向消息隊列提交兩次請求决侈,一次發(fā)送消息和一次確認(rèn)消息螺垢。如果確認(rèn)消息發(fā)送失敗了RocketMQ會定期掃描消息集群中的事務(wù)消息,這時候發(fā)現(xiàn)了Prepared消息赖歌,它會向消息發(fā)送者確認(rèn)枉圃,所以生產(chǎn)方需要實現(xiàn)一個check接口,RocketMQ會根據(jù)發(fā)送端設(shè)置的策略來決定是回滾還是繼續(xù)發(fā)送確認(rèn)消息庐冯。這樣就保證了消息發(fā)送與本地事務(wù)同時成功或同時失敗孽亲。

  • 系統(tǒng)A除了實現(xiàn)正常的業(yè)務(wù)流程外,還需提供一個事務(wù)詢問的接口展父,供消息中間件調(diào)用返劲。當(dāng)消息中間件收到一條事務(wù)型消息后便開始計時,如果到了超時時間也沒收到系統(tǒng)A發(fā)來的Commit或Rollback指令的話栖茉,就會主動調(diào)用系統(tǒng)A提供的事務(wù)詢問接口詢問該系統(tǒng)目前的狀態(tài)篮绿。該接口會返回三種結(jié)果:
    提交:將該消息投遞給系統(tǒng)B。
    回滾:直接將條消息丟棄吕漂。
    處理中:繼續(xù)等待亲配。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市痰娱,隨后出現(xiàn)的幾起案子弃榨,更是在濱河造成了極大的恐慌菩收,老刑警劉巖梨睁,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異娜饵,居然都是意外死亡坡贺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遍坟,“玉大人拳亿,你說我怎么就攤上這事≡赴椋” “怎么了肺魁?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長隔节。 經(jīng)常有香客問我鹅经,道長,這世上最難降的妖魔是什么怎诫? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任瘾晃,我火速辦了婚禮,結(jié)果婚禮上幻妓,老公的妹妹穿的比我還像新娘蹦误。我一直安慰自己,他們只是感情好肉津,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布强胰。 她就那樣靜靜地躺著,像睡著了一般妹沙。 火紅的嫁衣襯著肌膚如雪哪廓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天初烘,我揣著相機與錄音涡真,去河邊找鬼。 笑死肾筐,一個胖子當(dāng)著我的面吹牛哆料,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吗铐,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼东亦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了唬渗?” 一聲冷哼從身側(cè)響起典阵,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镊逝,沒想到半個月后壮啊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡撑蒜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年歹啼,在試婚紗的時候發(fā)現(xiàn)自己被綠了玄渗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡狸眼,死狀恐怖藤树,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拓萌,我是刑警寧澤岁钓,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站微王,受9級特大地震影響甜紫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骂远,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一囚霸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧激才,春花似錦拓型、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至东帅,卻和暖如春压固,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背靠闭。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工帐我, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人愧膀。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓拦键,卻偏偏與公主長得像,于是被迫代替她去往敵國和親檩淋。 傳聞我的和親對象是個殘疾皇子芬为,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容