Redis09-Redis事務(wù)

      網(wǎng)友投稿 891 2022-05-29

      前言

      上一篇我們介紹了Redis的持久化,這一篇我們接著來學(xué)習(xí)Redis的事務(wù)。將從如下幾個(gè)方面進(jìn)行闡述,事務(wù)的介紹,Redis事務(wù)的介紹,Redis事務(wù)與數(shù)據(jù)庫(kù)事務(wù)的區(qū)別。

      事務(wù)

      何為事務(wù)呢?我的理解是事務(wù)是一種機(jī)制,是一個(gè)不可分割的工作單元,要么都執(zhí)行,要么都不執(zhí)行。其具有如下四個(gè)特性:

      原子性(Atomicity)

      原子性是指事務(wù)是一個(gè)不可分割的工作單元,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。

      一致性(Consistency)

      一致性是指事務(wù)前后數(shù)據(jù)的完整性必須保持一致。

      隔離性(Isolation)

      隔離性是指多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),一個(gè)事務(wù)的執(zhí)行不應(yīng)影響其他事務(wù)的執(zhí)行,也就是說事務(wù)之間是相互隔離的。

      持久性(Durability)

      持久性是指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)的改變是持久的,接下來即使數(shù)據(jù)庫(kù)發(fā)生故障也不應(yīng)該對(duì)其有任何影響。在關(guān)系型數(shù)據(jù)庫(kù)中,事務(wù)執(zhí)行完之后,執(zhí)行結(jié)果就寫到了硬盤中。

      上面就是事務(wù)的四個(gè)特性,簡(jiǎn)稱ACID。關(guān)系型數(shù)據(jù)庫(kù)事務(wù)都滿足這四個(gè)特性。

      Redis的事務(wù)

      下面就是一個(gè)Redis事務(wù)的使用示例。

      Redis事務(wù)的簡(jiǎn)介

      Redis事務(wù)其實(shí)就是將多個(gè)命令包裹起來,一次性執(zhí)行。默認(rèn)是不開啟事務(wù)的。Redis事務(wù)從開始到執(zhí)行會(huì)經(jīng)歷如下三個(gè)階段:

      開始事務(wù)MULTI

      我們通過MULTI命令將執(zhí)行該命令的客戶端從非事務(wù)狀態(tài)切換至事務(wù)狀態(tài),通過在客戶端狀態(tài)的flags屬性中打開REDIS_MULIT標(biāo)識(shí)來完成的。

      127.0.0.1:6379> MULTI OK

      1

      2

      命令入隊(duì)

      如果客戶端正處于事務(wù)狀態(tài)時(shí),當(dāng)添加新命令時(shí),首先會(huì)判斷這個(gè)命令是否是EXEC,DISCARD,WATCH或者M(jìn)ULTI這四個(gè)命令, 如果不是的話則會(huì)把命令放入事務(wù)隊(duì)列中,每個(gè)Redis客戶端都有自己的事務(wù)隊(duì)列,它是一個(gè)multlCmd類型的數(shù)組,數(shù)組中的每個(gè)multlCmd類型的數(shù)組,數(shù)組中的每個(gè)multiCmd結(jié)構(gòu)都保存了一個(gè)已入隊(duì)命令的相關(guān)信息,包括指向命令實(shí)現(xiàn)函數(shù)的指針,命令的參數(shù),以及參數(shù)的數(shù)量,它以先進(jìn)先出(FIFO)的方式保存入隊(duì)的命令,較先入隊(duì)的命令會(huì)被放到數(shù)組前面,而較后入隊(duì)的命令會(huì)被放在數(shù)組的后面。

      127.0.0.1:6379> set name zhangsan QUEUED

      1

      2

      執(zhí)行事務(wù)EXEC

      當(dāng)一個(gè)處于事務(wù)狀態(tài)的客戶端向服務(wù)器發(fā)送EXEC命令時(shí),這個(gè)EXEC命令將立即被服務(wù)器執(zhí)行。服務(wù)器會(huì)遍歷這個(gè)客戶端的事務(wù)隊(duì)列,執(zhí)行隊(duì)列中保存的所有命令,最后將執(zhí)行命令所得的結(jié)果全部返回給客戶端。

      127.0.0.1:6379> exec 1) OK 2) "zhangsan" 3) OK

      1

      2

      3

      4

      Redis09-Redis事務(wù)

      Redis事務(wù)的相關(guān)特性

      Redis事務(wù)并不完全具有ACID這四種特性,它只具有一致性和隔離性。原因如下:

      Redis使用單線程的方式來執(zhí)行事務(wù)(以及事務(wù)隊(duì)列中的命令),并且服務(wù)器保證,在執(zhí)行事務(wù)期間不會(huì)中斷事務(wù),因此,Redis中的事務(wù)總是以串行的方式執(zhí)行,并且事務(wù)是具有隔離性的。

      Redis事務(wù)不過是一組包裹起來的命令,Redis并沒有做特殊的持久化工作,所以一般而言Redis事務(wù)不具有持久性,Redis的持久性策略可以看上一篇文章。

      Redis不支持事務(wù)回滾機(jī)制(rollback),即使事務(wù)隊(duì)列中的某個(gè)命令在執(zhí)行期間出現(xiàn)了錯(cuò)誤,整個(gè)事務(wù)也會(huì)繼續(xù)執(zhí)行下去,直到將事務(wù)隊(duì)列中的所有命令都執(zhí)行完畢為止,所以,Redis事務(wù)不支持原子性。如下圖所示:

      事務(wù)總是具有一致性的。即事務(wù)執(zhí)行前后數(shù)據(jù)是一致的。

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

      Redis實(shí)現(xiàn)事務(wù),是基于COMMANDS隊(duì)列的,也就是說,如果沒有開啟事務(wù),command將會(huì)被立即執(zhí)行并返回執(zhí)行結(jié)果,并且直接保存在內(nèi)存中,如果事務(wù)開啟,command不會(huì)被立即執(zhí)行,而是排入隊(duì)列并返回排隊(duì)狀態(tài)(具體依賴于客戶端(例如:spring-data-redis)自身實(shí)現(xiàn)),調(diào)用EXEC才會(huì)執(zhí)行COMMANDS隊(duì)列。

      WATCH命令

      WATCH命令是一個(gè)樂觀鎖,它可以在EXEC命令執(zhí)行之前,監(jiān)視任意數(shù)量的數(shù)據(jù)庫(kù)鍵,并在EXEC命令執(zhí)行時(shí),檢查被監(jiān)視的鍵是否至少有一個(gè)已經(jīng)被修改過了,如果是的話,服務(wù)器將拒絕執(zhí)行事務(wù),并向客戶端返回代表事務(wù)執(zhí)行失敗的空回復(fù)。如下所示:

      與MySQL事務(wù)的區(qū)別

      事務(wù)的命令不同

      MySQL事務(wù)的使用如下:

      BEGIN : 顯式地開啟一個(gè)事務(wù) COMMIT: 提交事務(wù) ROLLBACK: 結(jié)束用戶的事務(wù),并撤銷正在進(jìn)行的所有未提交的修改

      1

      2

      3

      而Redis事務(wù)的使用如下:

      MULTI: 標(biāo)記事務(wù)的開始 EXEC: 執(zhí)行事務(wù)的commands 隊(duì)列 DISCARD: 結(jié)束事務(wù),并清除commands隊(duì)列;

      1

      2

      3

      默認(rèn)狀態(tài)不同

      MySQL會(huì)默認(rèn)開啟一個(gè)事務(wù),且缺省設(shè)置是自動(dòng)提交,即每成功執(zhí)行一個(gè)SQL,一個(gè)事務(wù)就會(huì)馬上COMMIT,所以不能Rollback。當(dāng)然,我們?cè)谕粋€(gè)事務(wù)中執(zhí)行多個(gè)SQL時(shí),如果某個(gè)SQL執(zhí)行失敗了,則這個(gè)事務(wù)就會(huì)回滾掉。

      Redis默認(rèn)不會(huì)開啟事務(wù),即command會(huì)立即執(zhí)行,而不會(huì)排隊(duì),并且不支持Rollback。

      實(shí)現(xiàn)原理不同

      MySQL實(shí)現(xiàn)事務(wù),是基于UNDO/REDO日志,UNDO日志記錄修改前狀態(tài),ROLLBACK命令是基于UNDO日志實(shí)現(xiàn)的。

      REDO記錄修改后的狀態(tài),COMMIT命令是基于REDO日志實(shí)現(xiàn)的。

      在MySQL中無(wú)論是否開啟日志,SQL都會(huì)立即執(zhí)行并返回結(jié)果,只是事務(wù)開啟后執(zhí)行后的狀態(tài)記錄在REDO日志,執(zhí)行COMMIT之后,數(shù)據(jù)才會(huì)被寫入磁盤。

      參考

      《Redis設(shè)計(jì)與實(shí)現(xiàn)》

      總結(jié)

      本文簡(jiǎn)單介紹了Redis事務(wù)并將其與MySQL事務(wù)做了一下對(duì)比。Redis事務(wù)只有一致性和隔離性兩種特性,不支持原子性和持久性。其實(shí)現(xiàn)原理是基于COMMANDS隊(duì)列的,開啟事務(wù)之后,命令不會(huì)被立即執(zhí)行,而是排入隊(duì)列并返回排隊(duì)狀態(tài)。

      Redis 數(shù)據(jù)庫(kù)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Python:Python技巧之80個(gè)經(jīng)典題——課程筆記(一)
      下一篇:選取計(jì)數(shù)問題CSU 1759: Triangle(選三條邊構(gòu)成三角形)
      相關(guān)文章
      亚洲欧洲精品在线| 亚洲av无码电影网| 色噜噜噜噜亚洲第一| 亚洲一区二区三区写真 | 色婷婷六月亚洲婷婷丁香| 亚洲精品狼友在线播放| 国产亚洲精品va在线| 亚洲中文字幕在线乱码| 亚洲中文字幕无码中文字在线| 亚洲AV无码乱码在线观看性色扶 | 亚洲人成人77777网站| 国产精品亚洲综合一区| 国产精品亚洲mnbav网站| 亚洲中文字幕视频国产| 亚洲一区无码精品色| 中文字幕无码精品亚洲资源网| 亚洲中文字幕成人在线| 中文字幕亚洲乱码熟女一区二区| 久久久久亚洲AV成人网人人软件| 久久久久国产亚洲AV麻豆| 亚洲无人区午夜福利码高清完整版| 亚洲深深色噜噜狠狠爱网站| 亚洲精品你懂的在线观看| 亚洲AV无码乱码在线观看富二代| 亚洲AV永久无码精品成人| 亚洲高清在线观看| 亚洲精品动漫在线| 亚洲最大的黄色网| 亚洲国产AV一区二区三区四区 | 亚洲AV无码国产精品色午友在线| 亚洲成色在线综合网站| 香蕉蕉亚亚洲aav综合| 精品日韩亚洲AV无码一区二区三区 | 久久亚洲成a人片| 亚洲色图在线播放| 亚洲国产精品美女| 亚洲熟妇AV一区二区三区浪潮| 美国毛片亚洲社区在线观看 | 日韩精品亚洲专区在线观看| 亚洲免费无码在线| 亚洲成Av人片乱码色午夜|