Redis--事务理解
生活随笔
收集整理的這篇文章主要介紹了
Redis--事务理解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
事務(wù)
- 一個成熟的數(shù)據(jù)庫系統(tǒng)一般都會有事務(wù)的支持,Redis作為一個緩存數(shù)據(jù)庫也不例外,Redis的事務(wù)比之關(guān)系型數(shù)據(jù)庫mysql,oracle等算比較簡單的,Redis中無需理解那么多事務(wù)模型,可以直接使用。不過也正是因為簡單,redis的事務(wù)模型是不嚴謹?shù)?#xff0c;不能像關(guān)系型數(shù)據(jù)庫那么用Redis的事務(wù)。
Redis事務(wù)的基本用法
- 每個事務(wù)操作的基本過程都有如下begin, commit,和rollback,如下
- begin指令標識事務(wù)的開始
- commit指令標識事務(wù)的提交
- rollback指令標識事務(wù)的回滾
- Redis事務(wù)形式上基本相同指令分別是multi, exec,discard,
- multi:事務(wù)開始
- exec:事務(wù)執(zhí)行
- discard:事務(wù)丟棄
- 以上過程如下圖所示,所有指令在exec之前都不執(zhí)行,二手緩存在服務(wù)器的一個服務(wù)隊列中,服務(wù)器一旦收到exec指令,才開始執(zhí)行整個事務(wù)隊列,執(zhí)行完后一次性返回所有指令結(jié)果,因為Redis 是單線程,不用擔心自己在執(zhí)行隊列的時候被其他指令打攪,保證原子性。
原子性
- 事務(wù)的原子性指要么全部成功,要么都失敗,Redis的事務(wù)是非原子性的。如下案例。
- 如上案例是事務(wù)執(zhí)行到中間有一條指令是執(zhí)行失敗的,提示不能對字符串進行累加。但是后面的指令還是可以成功執(zhí)行,所有poorman 的值是正常設(shè)置
- 此處說明Redis事務(wù)不具備原子性,而僅僅是滿足了事務(wù)的“隔離性”中的串行化-----當前執(zhí)行的事務(wù)有不被其他事務(wù)打斷的權(quán)利。
discard(丟棄)
- Redis為事務(wù)提供discard指令,用于丟棄事務(wù)緩存隊列中所有指令,在exec執(zhí)行之前。
- 執(zhí)行discard后,隊列中所有指令都沒有執(zhí)行,我們執(zhí)行exec后提示無法執(zhí)行空的隊列
Redis事務(wù)的優(yōu)化
- Redis事務(wù)在發(fā)送每個指令到事務(wù)隊列緩存時候需要經(jīng)一次網(wǎng)絡(luò)讀寫,當一個事務(wù)內(nèi)部指令較多,需要的IOShi就也會線性增加,所以同城Redis客戶端在執(zhí)行事務(wù)時候回結(jié)合pipeline一起使用,這樣可以將多次IO操作壓縮為單次。例如java中Redis的使用
watch
- 當有一個業(yè)務(wù)場景,Redis存儲賬戶余額,是一個整數(shù),多個客戶端并發(fā)修改余額,這個修改不是簡單的incrby,而是需要通過一個邏輯計算,但是Redis單指令無法完成,我們需要先取出,計算,在存儲。這樣就是去原子性,有并發(fā)問題:
- 方案一:我們用Redis分布式鎖來避免沖突,分布式鎖是悲觀鎖,只允許一方持有鎖,其他等待
- 方案二:Redis提供watch機制,是樂觀鎖,有watch我們又多了一種可以解決并發(fā)修改的方法。watch使用方法如下。
- watch會在事務(wù)開始之前叮囑一個或者多個關(guān)鍵變量,流程如下:
- 當事務(wù)執(zhí)行之后,執(zhí)行exec命令后要順序執(zhí)行緩存的指令隊列
- Redis檢查關(guān)鍵變量watch之后是否被修改
- 如果被變量被修改過,exec指令將返回null,通知客戶端執(zhí)行失敗,此時我們可以重試或者其他邏輯
注意
- Redis禁止在multi 和exec之間執(zhí)行watch,必須在multi之前執(zhí)行watch,否則拋出異常。
上一篇:Redis持久化-深入理解AOF,RDB
下一篇:Redis存儲優(yōu)化–小對象壓縮
總結(jié)
以上是生活随笔為你收集整理的Redis--事务理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 胶囊胃镜一次多少钱
- 下一篇: Redis存储优化--小对象压缩