0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

剖析!Redis事務(wù)實(shí)現(xiàn)原理

張康康 ? 2019-07-29 18:27 ? 次閱讀

作者 | Video++極鏈科后端Team劉聰

整理 | 包包

所謂事務(wù)(Transaction) ,是指作為單個(gè)邏輯工作單元執(zhí)行的一系列操作。事務(wù)必須滿足ACID原則(原子性、一致性、隔離性和持久性)。簡(jiǎn)單來說事務(wù)其實(shí)就是打包一組操作(或者命令)作為一個(gè)整體,在事務(wù)處理時(shí)將順序執(zhí)行這些操作,并返回結(jié)果,如果其中任何一個(gè)環(huán)節(jié)出錯(cuò),所有的操作將被回滾。

在Redis中實(shí)現(xiàn)事務(wù)主要依靠以下幾個(gè)命令來實(shí)現(xiàn):

剖析!Redis事務(wù)實(shí)現(xiàn)原理


Redis事務(wù)從開始到結(jié)束通常會(huì)通過三個(gè)階段:

1.事務(wù)開始

2.命令入隊(duì)

3.事務(wù)執(zhí)行

以下是一個(gè)最簡(jiǎn)單的Redis事務(wù)流程:

剖析!Redis事務(wù)實(shí)現(xiàn)原理


第一步跟其他的關(guān)系型數(shù)據(jù)庫類似,也是需要開啟一個(gè)事務(wù),在Redis中的命令如下:

剖析!Redis事務(wù)實(shí)現(xiàn)原理


Redis中使用MULTI命令標(biāo)記事務(wù)的開始,可以理解為在傳統(tǒng)關(guān)系型數(shù)據(jù)庫中的BEGIN TRANCATION語句,Redis將執(zhí)行該命令的客戶端從非事務(wù)狀態(tài)切換成事務(wù)狀態(tài),這一切換是通過在客戶端狀態(tài)的flags屬性中打開REDIS_MULTI標(biāo)識(shí)完成, 我們看下Redis中對(duì)應(yīng)部分的源碼實(shí)現(xiàn):

剖析!Redis事務(wù)實(shí)現(xiàn)原理


在打開事務(wù)標(biāo)識(shí)的客戶端里,這些命令都會(huì)被暫存到一個(gè)命令隊(duì)列里,不會(huì)因?yàn)橛脩魰?huì)的輸入而立即執(zhí)行。

第二步就是執(zhí)行事務(wù)內(nèi)路基,即真正的業(yè)務(wù)邏輯:

剖析!Redis事務(wù)實(shí)現(xiàn)原理


最后一個(gè)階段是提交事務(wù)(或者回滾事務(wù)):

剖析!Redis事務(wù)實(shí)現(xiàn)原理


這兩個(gè)命令可被視為等同于關(guān)系型數(shù)據(jù)庫中的COMMIT/ROLLBACK語句。

這里需要注意的是,在客戶端打開了事務(wù)標(biāo)識(shí)后,只有命令:EXEC,DISCARD,WATCH,MULTI命令會(huì)被立即執(zhí)行,其它命令服務(wù)器不會(huì)立即執(zhí)行,而是將這些命令放入到一個(gè)事務(wù)隊(duì)列里面,然后向客戶端返回一個(gè)QUEUED回復(fù) ;Redis客戶端有自己的事務(wù)狀態(tài),這個(gè)狀態(tài)保存在客戶端狀態(tài)mstate屬性中,mstate的結(jié)構(gòu)體類型是multiState,我們看下multiState的定義:

剖析!Redis事務(wù)實(shí)現(xiàn)原理


我們?cè)倏聪陆Y(jié)構(gòu)體類型multiCmd的結(jié)構(gòu):

剖析!Redis事務(wù)實(shí)現(xiàn)原理


事務(wù)隊(duì)列以先進(jìn)先出的保存方法,較先入隊(duì)的命令會(huì)被放到數(shù)組的前面,而較后入隊(duì)的命令則會(huì)被放到數(shù)組的后面。

當(dāng)開啟事務(wù)標(biāo)識(shí)的客戶端發(fā)送EXEC命令的時(shí)候,服務(wù)器就會(huì)執(zhí)行,客戶端對(duì)應(yīng)的事務(wù)隊(duì)列里的命令,我們來看下EXEC 的實(shí)現(xiàn)細(xì)節(jié):

剖析!Redis事務(wù)實(shí)現(xiàn)原理


最后我們?cè)倩仡櫼幌率聞?wù)本身的特性, 在傳統(tǒng)關(guān)系型數(shù)據(jù)庫中的事務(wù)必須依靠ACID來保證事務(wù)的可靠性和安全性,在Redis中事務(wù)總是具有一致性(Consistency)和隔離性(Isolation),并且當(dāng)Redis運(yùn)行在某種特定的持久化模式下,事務(wù)也具有耐久性(Durability); 但是并不總是能夠保證原子性(Atomicity),在正常狀態(tài)下一個(gè)事務(wù)的所有命令是能按照原子性的原則執(zhí)行的,但是執(zhí)行的中途遇到錯(cuò)誤,不會(huì)回滾,而是繼續(xù)執(zhí)行后續(xù)命令, 如下:

剖析!Redis事務(wù)實(shí)現(xiàn)原理


如果在set k2 v2處失敗,set k1已成功不會(huì)回滾,set k3還會(huì)繼續(xù)執(zhí)行;Redis的事務(wù)和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫事務(wù)的最大區(qū)別在于,Redis不支持事務(wù)的回滾機(jī)制,即使事務(wù)隊(duì)列中的某個(gè)命令在執(zhí)行期間出現(xiàn)錯(cuò)誤,整個(gè)事務(wù)也會(huì)繼續(xù)執(zhí)行下去,直到將事務(wù)隊(duì)列中的所有命令都執(zhí)行完畢為止,我們看下面的例子:

剖析!Redis事務(wù)實(shí)現(xiàn)原理


Redis的作者在事務(wù)功能的文檔中解釋說,不支持事務(wù)回滾是因?yàn)檫@種復(fù)雜的功能和Redis追求的簡(jiǎn)單高效的設(shè)計(jì)主旨不符合,并且他認(rèn)為,Redis事務(wù)的執(zhí)行時(shí),錯(cuò)誤通常都是編程錯(cuò)誤造成的,這種錯(cuò)誤通常只會(huì)出現(xiàn)在開發(fā)環(huán)境中,而很少會(huì)在實(shí)際的生產(chǎn)環(huán)境中出現(xiàn),所以他認(rèn)為沒有必要為Redis開發(fā)事務(wù)回滾功能。所以我們?cè)谟懻揜edis事務(wù)回滾的時(shí)候,一定要區(qū)分命令發(fā)生錯(cuò)誤的時(shí)候。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Spring事務(wù)實(shí)現(xiàn)原理

    這些操作。 spring事務(wù)有編程式事務(wù)和聲明式事務(wù)兩種實(shí)現(xiàn)方式。編程式事務(wù)是通過編寫代碼來管理事務(wù)
    的頭像 發(fā)表于 11-08 10:10 ?170次閱讀
    Spring<b class='flag-5'>事務(wù)實(shí)現(xiàn)</b>原理

    Redis開源版與Redis企業(yè)版,怎么選用?

    點(diǎn)擊“藍(lán)字”關(guān)注我們數(shù)以千計(jì)的企業(yè)和數(shù)以百萬計(jì)的開發(fā)人員Redis開源版來構(gòu)建應(yīng)用程序。但隨著用戶數(shù)量、數(shù)據(jù)量和地區(qū)性的增加,成本、可擴(kuò)展性、運(yùn)營(yíng)和可用性等問題也隨之而來。Redis企業(yè)版
    的頭像 發(fā)表于 04-04 08:04 ?897次閱讀
    <b class='flag-5'>Redis</b>開源版與<b class='flag-5'>Redis</b>企業(yè)版,怎么選用?

    Redis實(shí)現(xiàn)分布式多規(guī)則限流的方式介紹

    市面上很多介紹 Redis 如何實(shí)現(xiàn)限流的,但是大部分都有一個(gè)缺點(diǎn),就是只能實(shí)現(xiàn)單一的限流,比如 1 分鐘訪問 1 次或者 60 分鐘訪問 10 次這種,但是如果想一個(gè)接口兩種規(guī)則都需要滿足呢,我們的項(xiàng)目又是分布式項(xiàng)目,應(yīng)該如何
    的頭像 發(fā)表于 02-26 10:07 ?429次閱讀
    <b class='flag-5'>Redis</b><b class='flag-5'>實(shí)現(xiàn)</b>分布式多規(guī)則限流的方式介紹

    Redis可以實(shí)現(xiàn)消息中間件MQ的功能

    是一種通信模式:發(fā)送者(PUBLISH)發(fā)送消息,訂閱者(SUBSCRIBE)接收消息,可以實(shí)現(xiàn)進(jìn)程間的消息傳遞   Redis可以實(shí)現(xiàn)消息中間件MQ的功能,通過發(fā)布訂閱實(shí)現(xiàn)消息
    的頭像 發(fā)表于 01-25 14:48 ?857次閱讀
    <b class='flag-5'>Redis</b>可以<b class='flag-5'>實(shí)現(xiàn)</b>消息中間件MQ的功能

    Redis的LRU實(shí)現(xiàn)和應(yīng)用

    在編程中,計(jì)數(shù)器是一種基本但強(qiáng)大的工具,用于跟蹤和管理數(shù)據(jù)和資源。本文將深入探討不同類型的計(jì)數(shù)器的應(yīng)用,從Redis的LRU(最近最少使用)緩存淘汰算法的實(shí)現(xiàn),到如何在內(nèi)存受限的環(huán)境中有效地使用計(jì)數(shù)器,再到普通計(jì)數(shù)器的巧妙應(yīng)用。
    的頭像 發(fā)表于 12-15 09:24 ?556次閱讀

    redis數(shù)據(jù)結(jié)構(gòu)的底層實(shí)現(xiàn)

    Redis是一種內(nèi)存鍵值數(shù)據(jù)庫,常用于緩存、消息隊(duì)列、實(shí)時(shí)數(shù)據(jù)分析等場(chǎng)景。它的高性能得益于其精心設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)和底層實(shí)現(xiàn)。本文將詳細(xì)介紹Redis常用的數(shù)據(jù)結(jié)構(gòu)和它們的底層實(shí)現(xiàn)。
    的頭像 發(fā)表于 12-05 10:14 ?570次閱讀

    redis容器內(nèi)怎么查看redis日志

    redis是一款流行的開源內(nèi)存數(shù)據(jù)庫,常用于緩存、消息隊(duì)列、任務(wù)管理等場(chǎng)景。在使用redis時(shí),了解如何查看redis日志對(duì)于排查問題、監(jiān)控性能和分析應(yīng)用程序行為非常重要。在本文中,我們將介紹在
    的頭像 發(fā)表于 12-05 10:10 ?3387次閱讀

    redis持久化機(jī)制和如何實(shí)現(xiàn)持久化

    Redis是一款高性能的非關(guān)系型數(shù)據(jù)庫,其持久化機(jī)制是保證數(shù)據(jù)在重啟后仍能夠保存的關(guān)鍵。Redis提供了兩種方式來實(shí)現(xiàn)持久化:RDB(Redis DataBase)和AOF(Appen
    的頭像 發(fā)表于 12-05 10:02 ?428次閱讀

    redis hash底層實(shí)現(xiàn)原理

    數(shù)據(jù)結(jié)構(gòu)是如何實(shí)現(xiàn)的呢?本文將詳細(xì)介紹Redis哈希底層的實(shí)現(xiàn)原理。 在Redis中,每個(gè)哈希都是由一個(gè)類似于字典(Dictionary)的結(jié)構(gòu)實(shí)現(xiàn)
    的頭像 發(fā)表于 12-04 16:27 ?542次閱讀

    如何實(shí)現(xiàn)Redis分布式鎖

    機(jī)制,下面將詳細(xì)介紹如何實(shí)現(xiàn)Redis分布式鎖。 一、引言 在分布式系統(tǒng)中,多個(gè)節(jié)點(diǎn)可能同時(shí)讀寫同一共享資源。如果沒有實(shí)現(xiàn)互斥訪問和同步機(jī)制,就會(huì)產(chǎn)生數(shù)據(jù)不一致和競(jìng)態(tài)條件等問題。解決這個(gè)問題的一種方法是使用分布式鎖,在訪問共享
    的頭像 發(fā)表于 12-04 11:24 ?632次閱讀

    Java redis鎖怎么實(shí)現(xiàn)

    在Java中實(shí)現(xiàn)Redis鎖涉及到以下幾個(gè)方面:Redis的安裝配置、Redis連接池的使用、Redis數(shù)據(jù)結(jié)構(gòu)的選擇、
    的頭像 發(fā)表于 12-04 10:47 ?1086次閱讀

    Redis工具集的實(shí)現(xiàn)和使用

    Redis 基本上是互聯(lián)網(wǎng)公司必備的工具了,Redis的應(yīng)用場(chǎng)景實(shí)在太多了,但是有很多相似的功能如果每個(gè)項(xiàng)目都要實(shí)現(xiàn)一遍就顯得太麻煩了,所以為了方便,我打算開發(fā)一個(gè)基于 Redis
    的頭像 發(fā)表于 12-03 17:32 ?1165次閱讀
    <b class='flag-5'>Redis</b>工具集的<b class='flag-5'>實(shí)現(xiàn)</b>和使用

    Redis的分頁+多條件模糊查詢組合實(shí)現(xiàn)方案

    Redis是key-value類型的內(nèi)存數(shù)據(jù)庫,通過key直接取數(shù)據(jù)雖然很方便,但是并未提供像mysql那樣方便的sql條件查詢支持。因此我們需要借助Redis提供的結(jié)構(gòu)和功能去自己實(shí)現(xiàn)模糊條件查詢功能。
    的頭像 發(fā)表于 11-20 14:26 ?831次閱讀
    <b class='flag-5'>Redis</b>的分頁+多條件模糊查詢組合<b class='flag-5'>實(shí)現(xiàn)</b>方案

    redis分布式鎖如何實(shí)現(xiàn)鎖等待

    Redis是一種高性能的鍵值存儲(chǔ)系統(tǒng),它除了提供基本的數(shù)據(jù)緩存功能外,還支持一些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和功能,例如發(fā)布訂閱、事務(wù)、持久化等。其中,Redis的分布式鎖是其常用的功能之一,可以用于解決多個(gè)
    的頭像 發(fā)表于 11-16 11:31 ?1122次閱讀

    redis分布式鎖如何實(shí)現(xiàn)

    Redis分布式鎖是一種基于Redis實(shí)現(xiàn)的機(jī)制,可以用于多個(gè)進(jìn)程或多臺(tái)服務(wù)器之間對(duì)共享資源的并發(fā)訪問控制。在分布式系統(tǒng)中,由于多個(gè)進(jìn)程或多臺(tái)服務(wù)器同時(shí)訪問共享資源,可能會(huì)發(fā)生數(shù)據(jù)競(jìng)爭(zhēng)和資源沖突
    的頭像 發(fā)表于 11-16 11:29 ?485次閱讀