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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
再談分布式事務(wù),你了解多少?

三年前,我寫了第一篇和分布式事務(wù)相關(guān)的文章再有人問你分布式事務(wù),把這篇扔給他,后面陸續(xù)也寫了一些和分布式事務(wù)相關(guān)的文章:

  • 如何能在實戰(zhàn)中完成分布式事務(wù)
  • 深度剖析一站式分布式事務(wù)方案Seata-Server
  • 深度剖析一站式分布式事務(wù)方案Seata-Cient
  • 解密分布式事務(wù)框架-Fescar

時隔三年,回看之前的文章,之前的確也有很多漏掉的一些知識,所以今天在這里再次和大家總結(jié)下分布式事務(wù)相關(guān)的東西。

事務(wù)

首先還是先說一下事務(wù)的定義吧,事務(wù)的英語是transaction,我們查找詞典可以發(fā)現(xiàn)這個單詞的中文解釋是交易,買賣等含義,所以我們可以知道事務(wù)一定和交易密不可分他們才能共享一個英文單詞,而交易的定義是什么呢?有句俗話說得好,一手交錢,一手交貨,那這個就是交易的規(guī)則,而這個同時也是事務(wù)的定義。那么事務(wù)的官方定義是什么呢?

事務(wù)是一系列操作的集合,這些操作要么都做,要么都不做,是一個不可分割的工作單位,是數(shù)據(jù)庫環(huán)境中的最小工作單元。

可以發(fā)現(xiàn)這個基本和我們一手交錢,一手交貨很像,的確在現(xiàn)實的開發(fā)環(huán)境中,在交易的業(yè)務(wù)中對事務(wù)的保證特別看重,而一些社交類的業(yè)務(wù),和資金關(guān)系不大的,比如點贊數(shù),評論數(shù),是不會對事務(wù)特別看重,這些應(yīng)該關(guān)注的是性能。

事務(wù)的類型

之前的文章都沒有介紹過事務(wù)的類型相關(guān),直到之前看了一篇文章,才知道事務(wù)是分了5種類型的,這里也介紹給大家:

扁平事務(wù)

我們?nèi)粘J褂玫幕径际潜馄绞聞?wù),以begin開始,然后以commit 或者 rollback結(jié)束.

begin;
do xxxx;
commit/rollback;

帶保存點的扁平事務(wù)

增加了SavePoint機制,內(nèi)存保存,如果數(shù)據(jù)庫宕機,savepoint將會丟失。

begin

insert into xxx

savepoint a

insert into yyy

rollback to a

這里的rollback to a只會回滾到保存點a這里,不會整個事務(wù)都回滾

鏈式事務(wù)

當我們提交事務(wù)后,相當于執(zhí)行了 COMMIT AND CHAIN,也就是開啟一個鏈式事務(wù),即當我們提交事務(wù)之后會開啟一個相同隔離級別的事務(wù)。如果回滾只會回滾當前節(jié)點。

通過下面sql語句可以再mysql里面查到當前是否開啟鏈式模式,以及如何開啟

select @@completion_type
set @@completion_type = 1 // 0無鏈式,

嵌套事務(wù)

  • 嵌套事務(wù)可以是一棵樹,其中的葉節(jié)點可以使扁平事務(wù),也可以是嵌套事務(wù),但是都叫做子事務(wù)
  • 某個節(jié)點回滾只影響當前節(jié)點下面所有的事務(wù)
  • 子節(jié)點的提交是會根據(jù)父節(jié)點提交才會最后提交,也就說,所有事務(wù)的保存只能再最頂層提交,才會生效。
  • mysql不支持嵌套事務(wù),Oracle支持

分布式事務(wù)

通常是一個在分布式環(huán)境下運行的扁平事務(wù),需要根據(jù)數(shù)據(jù)所在位置訪問網(wǎng)絡(luò)中的不同節(jié)點,一般來說對于分布式事務(wù),其同樣需要滿足單機 ACID 特性,要么都發(fā)生,要么都失效。但是實際實現(xiàn)的情況,可能遠比理想的更為復(fù)雜,所以通常會降低要求。

單機事務(wù)

上面講了五種類型的事務(wù),前4種其實都可以歸結(jié)為單機事務(wù),而單機事務(wù)也是后端程序員中經(jīng)常接觸到的,所以先簡單講講單機事務(wù)的核心關(guān)鍵點:

ACID

ACID是單機事務(wù)的四大特性,由這四個特性可以定義到底什么條件下才能算作事務(wù)。

  • A:原子性——事務(wù)內(nèi)的操作要么全部提交,要么全部回滾。
  • C:一致性——一個事務(wù)執(zhí)行之前和執(zhí)行之后數(shù)據(jù)庫都必須處于一致性狀態(tài)(數(shù)據(jù)庫的數(shù)據(jù)要么處于事務(wù)前的狀態(tài),要么處于事務(wù)后的狀態(tài))。
  • I:隔離性—— 在并發(fā)環(huán)境中,當不同的事務(wù)同時操縱相同的數(shù)據(jù)時,每個事務(wù)都有各自的完整數(shù)據(jù)空間。
  • D:持久性——事務(wù)成功結(jié)束,它對數(shù)據(jù)庫所做的更新就必須永久保存下來。即使發(fā)生系統(tǒng)崩潰,重新啟動數(shù)據(jù)庫系統(tǒng)后,數(shù)據(jù)庫還能恢復(fù)到事務(wù)成功結(jié)束時的狀態(tài)

實現(xiàn)關(guān)鍵

這里只講一下mysql的一些實現(xiàn)關(guān)鍵:

整體來說事務(wù)的ACID是通過InnoDB日志和鎖來保證:。

  • 事務(wù)的隔離性是通過數(shù)據(jù)庫鎖的機制實現(xiàn)的
  • 持久性通過redolog(重做日志)來實現(xiàn)。
  • 原子性通過Undolog來實現(xiàn)。
  • 一致性依靠三面上個特性來實現(xiàn)

redolog,undolog,binlog通常會容易搞混淆,這里簡單說一下

undolog:用于回滾和mvcc,可以理解他用于記錄之前版本的數(shù)據(jù)。

redolog:數(shù)據(jù)庫為了加快刷盤速度,采用了WAL的方式,也就是先順序預(yù)寫日志,然后再異步去刷盤,而redolog就是順序?qū)懭罩镜漠a(chǎn)物。

binlog:上面都是innodb引擎的日志,binlog是mysql-server的日志,用于主從同步等作用。

代碼使用

java程序員的話如果使用的是spring,那么使用本地事務(wù)會有兩種手段:

聲明式事務(wù)

其實就是直接加個注解,spring自己會做一個切面代理,然后使用事務(wù),這種方法使用得應(yīng)該也是最多的,因為他是最簡單的,但是說如果只想控制這個方法部分代碼進入事務(wù),或者調(diào)用同一個類的方法使用事務(wù),那就不太能使用這種方法。

編程式事務(wù)

編程式事務(wù),實現(xiàn)起來稍顯麻煩,需要自己手寫很多代碼,但是能解決上面說的那個問題。這種方式更加靈活多變。

分布式事務(wù)

為什么需要分布式事務(wù)

我們會發(fā)現(xiàn)分布式事務(wù)在最近幾年里提到的聲音越來越多,這是究竟為什么呢?在《架構(gòu)即未來》這本書中提到了AKF模型是軟件架構(gòu)擴展的基礎(chǔ)模型

如上圖,如果我們要對一個軟件進行擴展,那么需要以AKF模型為基礎(chǔ),從三個維度進行擴展。

  • X軸:x軸的意思就是將以前的單機,變成集群,從臺機器,擴容成N臺。
  • Y軸:以前的單體服務(wù)將所有業(yè)務(wù)代碼都寫在一個服務(wù)里面,而Y軸做的就是將這些業(yè)務(wù)模塊分開,拆分成微服務(wù)。
  • Z軸:很多業(yè)務(wù)瓶頸在數(shù)據(jù)庫,通常我們可以做數(shù)據(jù)庫分庫分表,單元化等等

在Y軸中我們之前的單體服務(wù)被拆分成了多個服務(wù),那就有可能以前一個事務(wù)的內(nèi)容,可能出現(xiàn)在了多個服務(wù)中,比如一個訂單扣除積分和優(yōu)惠券,之前是一個服務(wù),如果拆分出來了有積分服務(wù)和優(yōu)惠券服務(wù),那么我們之前的本地事務(wù)就會失效,就需要引入分布式服務(wù)來保證一個訂單中的全部扣減都是成功的。

在Z軸中,如果我們做了分庫分表,也會破壞本地事務(wù),如果大家都是一個庫自然還能使用分庫分表,但如果操作了不同庫那么就無法保證事務(wù),那么也需要引入分布式事務(wù)。

而AKF又是現(xiàn)代軟件擴展的基礎(chǔ)模型,三者有其二可能都需要引入分布式事務(wù),所以,如果要對軟件進行擴展,那么分布式事務(wù)必不可少。

分布式的理論知識

CAP和BASE的理論知識應(yīng)該很多人都知道,但是我這里還是需要介紹一下,因為分布式事務(wù)離不開這兩個東西。

CAP

CAP定理,又被叫作布魯爾定理。CAP是分布式系統(tǒng)的入門理論。

  • C (一致性):對某個指定的客戶端來說,讀操作能返回最新的寫操作。對于數(shù)據(jù)分布在不同節(jié)點上的數(shù)據(jù)上來說,如果在某個節(jié)點更新了數(shù)據(jù),那么在其他節(jié)點如果都能讀取到這個最新的數(shù)據(jù),那么就稱為強一致,如果有某個節(jié)點沒有讀取到,那就是分布式不一致。
  • A (可用性):非故障的節(jié)點在合理的時間內(nèi)返回合理的響應(yīng)(不是錯誤和超時的響應(yīng))??捎眯缘膬蓚€關(guān)鍵一個是合理的時間,一個是合理的響應(yīng)。合理的時間指的是請求不能無限被阻塞,應(yīng)該在合理的時間給出返回。合理的響應(yīng)指的是系統(tǒng)應(yīng)該明確返回結(jié)果并且結(jié)果是正確的,這里的正確指的是比如應(yīng)該返回50,而不是返回40。
  • P (分區(qū)容錯性):當出現(xiàn)網(wǎng)絡(luò)分區(qū)后,系統(tǒng)能夠繼續(xù)工作。打個比方,這里個集群有多臺機器,有臺機器網(wǎng)絡(luò)出現(xiàn)了問題,但是這個集群仍然可以正常工作。

BASE

BASE 是 Basically Available(基本可用)、Soft state(軟狀態(tài))和 Eventually consistent (最終一致性)三個短語的縮寫。是對CAP中AP的一個擴展。

1.基本可用:分布式系統(tǒng)在出現(xiàn)故障時,允許損失部分可用功能,保證核心功能可用。

2.軟狀態(tài):允許系統(tǒng)中存在中間狀態(tài),這個狀態(tài)不影響系統(tǒng)可用性,這里指的是CAP中的不一致。

3.最終一致:最終一致是指經(jīng)過一段時間后,所有節(jié)點數(shù)據(jù)都將會達到一致。

BASE解決了CAP中理論沒有網(wǎng)絡(luò)延遲,在BASE中用軟狀態(tài)和最終一致,保證了延遲后的一致性。BASE和 ACID 是相反的,它完全不同于ACID的強一致性模型,而是通過犧牲強一致性來獲得可用性,并允許數(shù)據(jù)在一段時間內(nèi)是不一致的,但最終達到一致狀態(tài)。

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

剛性事務(wù)

剛性事務(wù)追求的是強一致性事務(wù)。

DTP/XA

DTP的XA規(guī)范(全稱為Distributed Transaction Processing The XA Specification)的制定者是X/Open,即現(xiàn)在的Open Group。

熟悉數(shù)據(jù)庫自帶的分布式事務(wù)支持的同學(xué),其實就知道這個就是XA,

這里的AP你可以理解成是我們自己的業(yè)務(wù)服務(wù),RM則是我們使用的數(shù)據(jù)庫通常都是使用mysql而mysql也自帶支持XA,TM可以是一個單獨的服務(wù),也可以是我們自己的業(yè)務(wù)服務(wù)承擔(dān),他的作用是做事務(wù)管理。如果是用mysql的話,使用XA有如下代碼:

XA BEGIN '123';
insert into xxx;
XA END '123'; // 鏈接斷開會失去這次事務(wù)
XA PREPARE '123'; // 二階段準備會持久化
XA COMMIT '123'; //prepare全部成功/或者有一個失敗就回滾

當然XA其實有很多缺點:

1.數(shù)據(jù)鎖定:數(shù)據(jù)在整個事務(wù)處理過程結(jié)束前,都被鎖定,讀寫都按隔離級別的定義約束起來。

2.協(xié)議阻塞:XA prepare 后,分支事務(wù)進入阻塞階段,收到 XA commit 或 XA rollback 前必須阻塞等待。

3.性能差:性能的損耗主要來自兩個方面:一方面,事務(wù)協(xié)調(diào)過程,增加單個事務(wù)的 RT;另一方面,并發(fā)事務(wù)數(shù)據(jù)的鎖沖突,降低吞吐。

柔性事務(wù)

因為剛性事務(wù)的實現(xiàn)成本較大,對于現(xiàn)在互聯(lián)網(wǎng)的業(yè)務(wù)來說很多不愿意承受這么大的成本性能損失,愿意犧牲一定的一致性來保證性能,所以我們這里叫做柔性事務(wù)。

消息最終一致

適用于很多異步任務(wù),在我們的場景中,比如異步審核筆記,異步發(fā)放積分(適用于加法的業(yè)務(wù))。而消息最終一致也有兩種實現(xiàn)方法。

消息表

qmq實現(xiàn)事務(wù)消息的方法是利用的消息表。首先我們需要有一張這樣的消息表,用來和我們業(yè)務(wù)在同一個事務(wù)里面一起保存。

CREATE TABLE `msg_queue` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`topic` varchar(64) NOT NULL,
`nameServer` varchar(64) NOT NULL,
`status` smallint(6) NOT NULL DEFAULT '0' COMMENT '消息狀態(tài)',
`error` int unsigned NOT NULL DEFAULT '0' COMMENT '錯誤次數(shù)',
`create_time` datetime NOT NULL COMMENT '創(chuàng)建時間',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='記錄業(yè)務(wù)系統(tǒng)消息';

從上面圖上可以看出,我們會有單獨的task在不斷掃描我們的消息表,如果消息表沒有被刪除掉,代表之前沒有發(fā)送成功,那么我們需要做發(fā)送,這里需要說的是,我們一定要保證這個消息是冪等的,因為這里的發(fā)送完之后刪除消息,并不能保證數(shù)據(jù)是一致的,有可能一個消息會發(fā)送多次,最后才能被刪掉。

使用的代碼如下:

@Transactional
public void pay(Order order){
saveOrder(order);
messageProducer.sendMessage(buildMessage(order)); //要寫在最后
}

rocketmq事務(wù)消息

rockemq的事務(wù)消息如圖上所示分為四個階段:

  • 第一階段:先發(fā)送一個prepare消息,會獲取到一個prepare的消息id
  • 第二階段:執(zhí)行本地事務(wù),如果執(zhí)行成功,則發(fā)送commit/失敗則rollback。
  • 第三階段:rocketmq-server根據(jù)消息結(jié)果,如果成功就投遞給consumer,不成功則把消息刪除掉。
  • 第四階段: 如果二階段沒有上報消息結(jié)果,那就需要進行回查。

最大努力通知

適合于開放平臺,外部的第三方系統(tǒng)想要保證最終一致。比如微信,支付寶的開放平臺。下面我貼一個微信支付平臺的執(zhí)行流程:

從上面可以看到,最大努力通知需要保證兩點:

  • 有限次數(shù)的重試,一般重試策略采用指數(shù)退避
  • 需要提供查詢接口,來防止通知失敗。

TCC

做支付的同學(xué)比較常用的,雖然是柔性事物,但是目標是有剛性的效果。隔離性比較強。

舉個例子:有積分服務(wù),券服務(wù),余額服務(wù),如果用戶一次訂單想同時扣減這三個怎么能保證。用其他的模式可以嗎?

消息最終一致和最大努力通知,都不太適合,無法保證隔離型,用戶重復(fù)使用資產(chǎn)。XA性能差。

所以這里我們選擇使用了TCC,分三個方法:

  • try: 鎖定,通常用一個字段或者記錄。(演化成saga直接try commit合并)
  • commit: 提交資源
  • cancel:釋放資源

SAGA

Saga是30年前一篇數(shù)據(jù)庫倫理提到的一個概念。其核心思想是將長事務(wù)拆分為多個本地短事務(wù),由Saga事務(wù)協(xié)調(diào)器協(xié)調(diào),如果正常結(jié)束那就正常完成,如果某個步驟失敗,則根據(jù)相反順序一次調(diào)用補償操作。

  • 適用于無法提供TCC接口(遺留系統(tǒng),外部系統(tǒng)),一般來說提供提交 和 回滾接口即可 ,這里的可以看做業(yè)務(wù)上的接口,生成訂單 對應(yīng) 的刪除訂單就是回滾,不需要單獨命名回滾接口。
  • 不看隔離性,一階段就生效
  • 想異步執(zhí)行
  • 想支持正向重試(tcc,try 為什么不能正向重試,資源一直被業(yè)務(wù)隔離,需要釋放隔離性)

SEATA

當然上面介紹了很多種分布式事務(wù),有同學(xué)會想,說了這么多但是我該怎么實現(xiàn)呢?那我在這里推薦使用seata,seata 是一款開源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)下提供高性能和簡單易用的分布式事務(wù)服務(wù)。為用戶提供了 AT、TCC、SAGA 和 XA 事務(wù)模式。

有興趣的可以訪問seata官網(wǎng):https://seata.io/zh-cn 。我這里就不具體介紹了,或者看我之前的文章也有很多介紹。

最后

時隔這么久,再次寫了一下關(guān)于分布式事務(wù)相關(guān)的,這次算對之前的是補充,當然也算是對分布式事務(wù)的總結(jié)。希望大家能在自己的業(yè)務(wù)中能找到合適自己的分布式事務(wù)的方法。


當前標題:再談分布式事務(wù),你了解多少?
瀏覽地址:http://www.dlmjj.cn/article/djjdpid.html