更新時(shí)間:2021-08-17 10:20:30 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1481次
當(dāng)我們的單個(gè)數(shù)據(jù)庫的性能產(chǎn)生瓶頸的時(shí)候,我們可能會(huì)對(duì)數(shù)據(jù)庫進(jìn)行分區(qū)。這時(shí)候事務(wù)不能只依靠本地?cái)?shù)據(jù)庫對(duì)事務(wù)支持來實(shí)現(xiàn)了。
1.兩階段提交(2PC)
假設(shè)事務(wù)在a,b兩個(gè)數(shù)據(jù)庫上。那現(xiàn)在要對(duì)這兩個(gè)數(shù)據(jù)庫實(shí)現(xiàn)事務(wù)支持,就是分別操作a,b上的事務(wù),由一個(gè)中間件收集a,b操作的結(jié)果。若都成功了,就commit, 否則就回滾。

優(yōu)點(diǎn):強(qiáng)一致性。
缺點(diǎn):
(1)如commit到數(shù)據(jù)庫過程中出了問題,導(dǎo)致事務(wù)可能不會(huì)結(jié)束。
(2)性能差。涉及多次節(jié)點(diǎn)間的網(wǎng)絡(luò)通信,通信時(shí)間過長,導(dǎo)致事務(wù)時(shí)間過長,鎖定的資源也變長了,造成資源等待時(shí)間也過長。
2.補(bǔ)償事務(wù)(TCC)
TCC 其實(shí)就是采用的補(bǔ)償機(jī)制,其核心思想是:針對(duì)每個(gè)操作,都要注冊(cè)一個(gè)與其對(duì)應(yīng)的確認(rèn)和補(bǔ)償(撤銷)操作。它分為三個(gè)階段:
(1)Try階段主要是對(duì)業(yè)務(wù)系統(tǒng)做檢測及資源預(yù)留
(2)Confirm階段主要是對(duì)業(yè)務(wù)系統(tǒng)做確認(rèn)提交,Try階段執(zhí)行成功并開始執(zhí)行 Confirm階段時(shí),默認(rèn) Confirm階段是不會(huì)出錯(cuò)的。即:只要Try成功,Confirm一定成功。
(3)Cancel階段主要是在業(yè)務(wù)執(zhí)行錯(cuò)誤,需要回滾的狀態(tài)下執(zhí)行的業(yè)務(wù)取消,預(yù)留資源釋放。
優(yōu)點(diǎn):解決事務(wù)過長問題。
缺點(diǎn):需要編寫額外補(bǔ)償代碼,造成代碼龐大,難以維護(hù)。
RocketMQ第一階段發(fā)送Prepared消息時(shí),會(huì)拿到消息的地址,第二階段執(zhí)行本地事物,第三階段通過第一階段拿到的地址去訪問消息,并修改狀態(tài)。細(xì)心的讀者可能又發(fā)現(xiàn)問題了,如果確認(rèn)消息發(fā)送失敗了怎么辦?RocketMQ會(huì)定期掃描消息集群中的事物消息,這時(shí)候發(fā)現(xiàn)了Prepared消息,它會(huì)向消息發(fā)送者確認(rèn),Bob的錢到底是減了還是沒減呢?如果減了是回滾還是繼續(xù)發(fā)送確認(rèn)消息呢?RocketMQ會(huì)根據(jù)發(fā)送端設(shè)置的策略來決定是回滾還是繼續(xù)發(fā)送確認(rèn)消息。這樣就保證了消息發(fā)送與本地事務(wù)同時(shí)成功或同時(shí)失敗。
舉個(gè)例子: 去面館吃面。 先去收銀臺(tái)付錢, 收銀臺(tái)會(huì)給你一個(gè)小票, 并且通知廚房做面。 廚房做面失敗, 會(huì)有大堂經(jīng)理通知你失敗, 并退錢給你。 或者成功了,服務(wù)員把你端給你, 然后收回你的小票。消息隊(duì)列處理事務(wù)大概是這樣的過程。 這里的發(fā)票相當(dāng)于消息隊(duì)列中的消息。 付錢和收到做好的面可以看做1個(gè)事務(wù)要做的兩件事。 這里還有一些問題, 首先收銀員收了錢卻忘了給你小票呢? 這種情況先開個(gè)準(zhǔn)備付款小票, 當(dāng)收到錢后,再確認(rèn)已經(jīng)付款。 如果忘了給小票肯定還是有個(gè)準(zhǔn)備付款小票以及查詢付款記錄就知道是不是付款了。消息隊(duì)列還會(huì)重復(fù)消費(fèi), 還要注意查重。
4.當(dāng)做一個(gè)任務(wù)來處理
一個(gè)任務(wù)處理過錯(cuò)可能會(huì)有很多步驟, 一般程序做完一步就會(huì)寫入日志。 程序處理任務(wù)時(shí)崩潰時(shí)候, 我們可以通過日志判斷任務(wù)處理情況, 然后就可以準(zhǔn)確修復(fù)了。 我們這里可以這樣每處理完事務(wù)中一條sql, 就把一個(gè)唯一事務(wù)id作為記錄插入一個(gè)事務(wù)登記表中相當(dāng)于日志。 用一個(gè)模塊去掃描這些表就可以找出事務(wù)有問題的表然后去修復(fù)。這個(gè)方案想對(duì)實(shí)現(xiàn)起來簡單。
優(yōu)點(diǎn): 由于把事務(wù)拆成小的事務(wù), 性能更高。
缺點(diǎn):補(bǔ)償方案比較麻煩。
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"分布式數(shù)據(jù)庫事務(wù)詳解",希望對(duì)大家有幫助,想了解更多可查看Java分布式應(yīng)用教程。動(dòng)力節(jié)點(diǎn)在線學(xué)習(xí)教程,針對(duì)沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識(shí),讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)