日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
12張圖帶你徹底理解分布式事務(wù)產(chǎn)生的場(chǎng)景和解決方案

12張圖帶你徹底理解分布式事務(wù)產(chǎn)生的場(chǎng)景和解決方案

作者:冰河 2020-10-16 06:30:45

開發(fā)

前端

分布式 作者個(gè)人研發(fā)的在高并發(fā)場(chǎng)景下,提供的簡(jiǎn)單、穩(wěn)定、可擴(kuò)展的延遲消息隊(duì)列框架,具有精準(zhǔn)的定時(shí)任務(wù)和延遲隊(duì)列處理功能。自開源半年多以來(lái),已成功為十幾家中小型企業(yè)提供了精準(zhǔn)定時(shí)調(diào)度方案,經(jīng)受住了生產(chǎn)環(huán)境的考驗(yàn)。

作者個(gè)人研發(fā)的在高并發(fā)場(chǎng)景下,提供的簡(jiǎn)單、穩(wěn)定、可擴(kuò)展的延遲消息隊(duì)列框架,具有精準(zhǔn)的定時(shí)任務(wù)和延遲隊(duì)列處理功能。自開源半年多以來(lái),已成功為十幾家中小型企業(yè)提供了精準(zhǔn)定時(shí)調(diào)度方案,經(jīng)受住了生產(chǎn)環(huán)境的考驗(yàn)。為使更多童鞋受益,現(xiàn)給出開源框架地址:https://github.com/sunshinelyz/mykit-delay

PS: 歡迎各位Star源碼,也可以pr你牛逼哄哄的代碼。

寫在前面

寫這篇文章的背景是有個(gè)跟我關(guān)系不錯(cuò)的小伙伴去某大型互聯(lián)網(wǎng)公司面試,面試官問(wèn)了他關(guān)于分布式事務(wù)的問(wèn)題,不巧的是他確實(shí)對(duì)分布式事務(wù)掌握的不是很深入,面試的結(jié)果挺遺憾的。不過(guò),這位小伙伴還是挺樂(lè)觀的,讓我寫寫關(guān)于【分布式事務(wù)】的系列文章,想提升自己關(guān)于分布式事務(wù)的短板,那我就寫一個(gè)【分布式事務(wù)】專題吧,專題的內(nèi)容計(jì)劃是從原理、框架源碼到企業(yè)級(jí)實(shí)現(xiàn),這篇文章也算是整個(gè)專題的開篇吧。希望能夠?yàn)樾』锇閭儙?lái)實(shí)質(zhì)性的幫助。

本地事務(wù)

本地事務(wù)流程

在介紹分布式事務(wù)之前,我們先來(lái)看看本地事務(wù)。首先,我們先來(lái)一張圖。

由上圖,我們可以看出,本地事務(wù)由資源管理器(比如DBMS,數(shù)據(jù)庫(kù)管理系統(tǒng))在本地進(jìn)行管理。

本地事務(wù)的優(yōu)缺點(diǎn)

本地事務(wù)具備相應(yīng)的優(yōu)點(diǎn),也有其不足。

優(yōu)點(diǎn):

  • 支持嚴(yán)格的ACID屬性。
  • 可靠,事務(wù)實(shí)現(xiàn)的效率高(只是在本地操作)。
  • 可以只在RM(資源管理器)中操作事務(wù)。
  • 編程模型簡(jiǎn)單。

缺點(diǎn):

  • 缺乏分布式事務(wù)的處理能力。
  • 數(shù)據(jù)隔離的最小單元由RM(資源管理器決定),開發(fā)人員無(wú)法決定數(shù)據(jù)隔離的最小單元。比如:數(shù)據(jù)庫(kù)中的一條記錄等。

ACID屬性

說(shuō)起事務(wù),我們不得不提的就是事務(wù)的ACID屬性。

  • A(Atomic):原子性,構(gòu)成事務(wù)的所有操作,要么都執(zhí)行完成,要么全部不執(zhí)行,不可能出現(xiàn)部分成功部分失 敗的情況。
  • C(Consistency):一致性,在事務(wù)執(zhí)行前后,數(shù)據(jù)庫(kù)的一致性約束沒有被破壞。比如:張三向李四轉(zhuǎn)100元, 轉(zhuǎn)賬前和轉(zhuǎn)賬后的數(shù)據(jù)的正確狀態(tài)叫作一致性,如果出現(xiàn)張三轉(zhuǎn)出100元,李四賬戶沒有增加100元這就出現(xiàn)了數(shù) 據(jù)錯(cuò)誤,就沒有達(dá)到一致性。
  • I(Isolation):隔離性,數(shù)據(jù)庫(kù)中的事務(wù)一般都是并發(fā)的,隔離性是指并發(fā)的兩個(gè)事務(wù)的執(zhí)行互不干擾,一個(gè)事 務(wù)不能看到其他事務(wù)運(yùn)行過(guò)程的中間狀態(tài)。通過(guò)配置事務(wù)隔離級(jí)別可以避臟讀、重復(fù)讀等問(wèn)題。
  • D(Durability):持久性,事務(wù)完成之后,該事務(wù)對(duì)數(shù)據(jù)的更改會(huì)被持久化到數(shù)據(jù)庫(kù),且不會(huì)被回滾。

分布式事務(wù)

隨著業(yè)務(wù)的快速發(fā)展,網(wǎng)站系統(tǒng)往往由單體架構(gòu)逐漸演變?yōu)榉植际健⑽⒎?wù)架構(gòu),而對(duì)于數(shù)據(jù)庫(kù)則由單機(jī)數(shù)據(jù)庫(kù)架構(gòu)向分布式數(shù)據(jù)庫(kù)架構(gòu)轉(zhuǎn)變。此時(shí),我們會(huì)將一個(gè)大的應(yīng)用系統(tǒng)拆分為多個(gè)可以獨(dú)立部署的應(yīng)用服務(wù),需要各個(gè)服務(wù)之間進(jìn)行遠(yuǎn)程協(xié)作才能完成事務(wù)操作。

我們可以使用下圖來(lái)表示剛開始我們系統(tǒng)的單體架構(gòu)。

上圖中,我們將同一個(gè)項(xiàng)目中的不同模塊組織成不同的包來(lái)進(jìn)行管理,所有的程序代碼仍然是放在同一個(gè)項(xiàng)目中。

后續(xù)由于業(yè)務(wù)的發(fā)展,我們將其擴(kuò)展為分布式、微服務(wù)架構(gòu)。此時(shí),我們將一個(gè)大的項(xiàng)目拆分為一個(gè)個(gè)小的可以獨(dú)立部署的微服務(wù),每個(gè)微服務(wù)都有自己的數(shù)據(jù)庫(kù),如下所示。

又比如,在我們的程序中,經(jīng)常會(huì)在同一個(gè)事務(wù)中執(zhí)行類似如下的代碼來(lái)完成我們的需求。

  
 
 
 
  1. @Transactional(rollbackFor = Exception.class)
  2. public void submitOrder() {
  3.     orderDao.update(); // 更新訂單信息
  4.     accountService.update(); // 修改資金賬戶的金額
  5.     pointService.update(); //  修改積分
  6.     accountingService.insert(); // 插入交易流水
  7.     merchantNotifyService.notify(); // 通知支付結(jié)果
  8. }

上述代碼中的業(yè)務(wù),僅僅在submitOrder()方法上添加了一個(gè)@Transactional注解,這能夠在分布式場(chǎng)景下避免分布式事務(wù)的問(wèn)題嗎?很顯然是不行的。

如果上述代碼所對(duì)應(yīng)的:訂單信息、資金賬戶信息、積分信息、交易流水等信息分別存儲(chǔ)在不同的數(shù)據(jù)里,而支付完成后,通知的目標(biāo)系統(tǒng)的數(shù)據(jù)同樣是存儲(chǔ)在不同的數(shù)據(jù)庫(kù)中。此時(shí)就會(huì)產(chǎn)生分布式事務(wù)問(wèn)題。

分布式事務(wù)產(chǎn)生的場(chǎng)景

跨JVM進(jìn)程

當(dāng)我們將單體項(xiàng)目拆分為分布式、微服務(wù)項(xiàng)目之后,各個(gè)服務(wù)之間通過(guò)遠(yuǎn)程REST或者RPC調(diào)用來(lái)協(xié)同完成業(yè)務(wù)操作。典型的場(chǎng)景就是:商城系統(tǒng)中的訂單微服務(wù)和庫(kù)存微服務(wù),用戶在下單時(shí)會(huì)訪問(wèn)訂單微服務(wù),訂單微服務(wù)在生成訂單記錄時(shí),會(huì)調(diào)用庫(kù)存微服務(wù)來(lái)扣減庫(kù)存。各個(gè)微服務(wù)是部署在不同的JVM進(jìn)程中的,此時(shí),就會(huì)產(chǎn)生因跨JVM進(jìn)程而導(dǎo)致的分布式事務(wù)問(wèn)題。

跨數(shù)據(jù)庫(kù)實(shí)例

單體系統(tǒng)訪問(wèn)多個(gè)數(shù)據(jù)庫(kù)實(shí)例,也就是跨數(shù)據(jù)源訪問(wèn)時(shí)會(huì)產(chǎn)生分布式事務(wù)。例如,我們的系統(tǒng)中的訂單數(shù)據(jù)庫(kù)和交易數(shù)據(jù)庫(kù)是放在不同的數(shù)據(jù)庫(kù)實(shí)例中,當(dāng)用戶發(fā)起退款時(shí),會(huì)同時(shí)操作用戶的訂單數(shù)據(jù)庫(kù)和交易數(shù)據(jù)庫(kù),在交易數(shù)據(jù)庫(kù)中執(zhí)行退款操作,在訂單數(shù)據(jù)庫(kù)中將訂單的狀態(tài)變更為已退款。由于數(shù)據(jù)分布在不同的數(shù)據(jù)庫(kù)實(shí)例,需要通過(guò)不同的數(shù)據(jù)庫(kù)連接會(huì)話來(lái)操作數(shù)據(jù)庫(kù)中的數(shù)據(jù),此時(shí),就產(chǎn)生了分布式事務(wù)。

多服務(wù)單數(shù)據(jù)庫(kù)

多個(gè)微服務(wù)訪問(wèn)同一個(gè)數(shù)據(jù)庫(kù)。例如,訂單微服務(wù)和庫(kù)存微服務(wù)訪問(wèn)同一個(gè)數(shù)據(jù)庫(kù)也會(huì)產(chǎn)生分布式事務(wù),原因是:多個(gè)微服務(wù)訪問(wèn)同一個(gè)數(shù)據(jù)庫(kù),本質(zhì)上也是通過(guò)不同的數(shù)據(jù)庫(kù)會(huì)話來(lái)操作數(shù)據(jù)庫(kù),此時(shí)就會(huì)產(chǎn)生分布式事務(wù)。

注意:跨數(shù)據(jù)庫(kù)實(shí)例場(chǎng)景和多服務(wù)單數(shù)據(jù)庫(kù)場(chǎng)景,本質(zhì)上都是因?yàn)闀?huì)產(chǎn)生不同的數(shù)據(jù)庫(kù)會(huì)話來(lái)操作數(shù)據(jù)庫(kù)中的數(shù)據(jù),進(jìn)而產(chǎn)生分布式事務(wù)。這兩種場(chǎng)景是大家比較容易忽略的。

分布式事務(wù)解決方案

知道了分布式事務(wù)產(chǎn)生的場(chǎng)景后,接下來(lái),我們就聊聊分布式事務(wù)具體有哪些解決方案。

2PC方案

2PC即兩階段提交協(xié)議,是將整個(gè)事務(wù)流程分為兩個(gè)階段,準(zhǔn)備階段(Prepare phase)、提交階段(commit phase),2是指兩個(gè)階段,P是指準(zhǔn)備階段,C是指提交階段。

這里,我們用MySQL數(shù)據(jù)庫(kù)舉例,MySQL數(shù)據(jù)庫(kù)支持兩階段提交協(xié)議,可以分為成功和失敗兩種情況。

成功情況

失敗情況

具體流程如下:

準(zhǔn)備階段(Prepare phase): 事務(wù)管理器給每個(gè)參與者發(fā)送Prepare消息,每個(gè)數(shù)據(jù)庫(kù)參與者在本地執(zhí)行事 務(wù),并寫本地的Undo/Redo日志,此時(shí)事務(wù)沒有提交。(Undo日志是記錄修改前的數(shù)據(jù),用于數(shù)據(jù)庫(kù)回滾,Redo日志是記錄修改后的數(shù)據(jù),用于提交事務(wù)后寫入數(shù) 據(jù)文件)

提交階段(commit phase): 如果事務(wù)管理器收到了參與者的執(zhí)行失敗或者超時(shí)消息時(shí),直接給每個(gè)參與者 發(fā)送回滾(Rollback)消息;否則,發(fā)送提交(Commit)消息;參與者根據(jù)事務(wù)管理器的指令執(zhí)行提交或者回滾操 作,并釋放事務(wù)處理過(guò)程中使用的鎖資源。

使用2PC方案時(shí),需要注意的是:必須在最后階段釋放鎖資源。

可靠消息最終一致性方案

可靠消息最終一致性方案是指當(dāng)事務(wù)發(fā)起方執(zhí)行完成本地事務(wù)后并發(fā)出一條消息,事務(wù)參與方(消息消費(fèi)者)一定能 夠接收消息并處理事務(wù)成功,此方案強(qiáng)調(diào)的是只要消息發(fā)給事務(wù)參與方最終事務(wù)要達(dá)到一致。

事務(wù)發(fā)起方(消息生產(chǎn)方)將消息發(fā)給消息中間件,事務(wù)參與方從消息中間件接收消息,事務(wù)發(fā)起方和消息中間件 之間,事務(wù)參與方(消息消費(fèi)方)和消息中間件之間都是通過(guò)網(wǎng)絡(luò)通信,由于網(wǎng)絡(luò)通信的不確定性會(huì)導(dǎo)致分布式事 務(wù)問(wèn)題。 所以,我們?cè)诰唧w方案中會(huì)引入消息確認(rèn)服務(wù)和消息恢復(fù)服務(wù)。

使用可靠消息最終一致性方案時(shí)需要注意幾個(gè)問(wèn)題:

  • 本地事務(wù)與消息發(fā)送的原子性問(wèn)題。
  • 事務(wù)參與方接收消息的可靠性問(wèn)題。
  • 消息重復(fù)消費(fèi)的問(wèn)題(需要實(shí)現(xiàn)冪等)。

TCC方案

TCC分為三個(gè)階段:

  • Try 階段 是做業(yè)務(wù)檢查(一致性)及資源預(yù)留(隔離),此階段僅是一個(gè)初步操作,它和后續(xù)的Confirm 一起才能 真正構(gòu)成一個(gè)完整的業(yè)務(wù)邏輯。
  • Confirm 階段 是做確認(rèn)提交,Try階段所有分支事務(wù)執(zhí)行成功后開始執(zhí)行 Confirm。通常情況下,采用TCC則 認(rèn)為 Confirm階段是不會(huì)出錯(cuò)的。即:只要Try成功,Confirm一定成功。若Confirm階段真的出錯(cuò)了,需引 入重試機(jī)制或人工處理。
  • Cancel 階段 是在業(yè)務(wù)執(zhí)行錯(cuò)誤需要回滾的狀態(tài)下執(zhí)行分支事務(wù)的業(yè)務(wù)取消,預(yù)留資源釋放。通常情況下,采 用TCC則認(rèn)為Cancel階段也是一定成功的。若Cancel階段真的出錯(cuò)了,需引入重試機(jī)制或人工處理。

使用TCC分布式解決方案時(shí)需要注意空回滾、冪等、懸掛等問(wèn)題。

最大努力通知型方案

此種方案主要用于多個(gè)不同系統(tǒng)之前保證數(shù)據(jù)的最終一致性,大體如下圖所示。

使用最大努力通知型方案需要注意冪等和數(shù)據(jù)的回查操作。

好了,今天就到這兒吧,后續(xù)我們會(huì)針對(duì)每種分布式事務(wù)解決方案進(jìn)行具體介紹,下期見!!

本文轉(zhuǎn)載自微信公眾號(hào)「冰河技術(shù)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系冰河技術(shù)公眾號(hào)。


網(wǎng)站標(biāo)題:12張圖帶你徹底理解分布式事務(wù)產(chǎn)生的場(chǎng)景和解決方案
URL分享:http://www.dlmjj.cn/article/dpsigho.html