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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
簡單聊一聊Redis事務(wù)

通過這篇文章,你會(huì)了解

創(chuàng)新互聯(lián),為您提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作公司、網(wǎng)站營銷推廣、網(wǎng)站開發(fā)設(shè)計(jì),對(duì)服務(wù)展覽展示等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)及推廣經(jīng)驗(yàn)。創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司成立于2013年,提供專業(yè)網(wǎng)站制作報(bào)價(jià)服務(wù),我們深知市場的競爭激烈,認(rèn)真對(duì)待每位客戶,為客戶提供賞心悅目的作品。 與客戶共同發(fā)展進(jìn)步,是我們永遠(yuǎn)的責(zé)任!

  • Redis為什么要提供事務(wù)?
  • Redis事務(wù)基本指令和使用方法
  • CAS樂觀鎖是什么?
  • Redis事務(wù)為什么不支持回滾?

1. 為什么要用事務(wù)

我們知道Redis的單個(gè)命令是原子性的,比如get、set、mget、mset等指令。

原子性是指操作是不可分割的,在執(zhí)行完畢之前不會(huì)被任何其它任務(wù)或事件中斷,也就不會(huì)有并發(fā)的安全性問題

在涉及到多個(gè)命令的時(shí)候,如果需要把多個(gè)命令設(shè)置為一個(gè)不可分割的處理序列,就需要用到事務(wù)了。

比如,招財(cái)和陀螺各有100元,招財(cái)給陀螺轉(zhuǎn)了10元,這時(shí)候需要在Redis中把招財(cái)?shù)慕痤~總數(shù)-10,同時(shí)需要把陀螺的金額總數(shù)+10。這兩個(gè)操作要么同時(shí)成功,要么同時(shí)失敗,這時(shí)候就需要事務(wù)了。

實(shí)際上,Redis連這個(gè)簡單的需求都沒辦法完美做到,至于為啥,接著往下看吧

2. 事務(wù)的用法

2.1 5個(gè)基本指令

Redis提供了以下5個(gè)基本指令,先混個(gè)眼熟就行,接下來在案例中進(jìn)行實(shí)操,想記不住都難

  • MULTI
  • EXEC
  • DISCARD
  • WATCH
  • UNWATCH

2.2 案例演示

案例場景:招財(cái)和陀螺各有100元,招財(cái)給陀螺轉(zhuǎn)了10元,這時(shí)候需要在Redis中把招財(cái)?shù)慕痤~-10,同時(shí)需要把陀螺的金額+10。

2.2.1 事務(wù)提交

我們首先為陀螺和招財(cái)初始化自己的金額;然后使用MULTI命令顯式開啟Redis事務(wù)。 該命令總是直接返回OK。此時(shí)用戶可以發(fā)送多個(gè)指令,Redis不會(huì)立刻執(zhí)行這些命令,而是將這些指令依次放入當(dāng)前事務(wù)的指令隊(duì)列中;EXEC被調(diào)用后,所有的命令才會(huì)被依次執(zhí)行。

# 給陀螺初始化100元
127.0.0.1:6379> set tuoluo 100
OK
# 給招財(cái)初始化100元
127.0.0.1:6379> set zhaocai 100
OK
# 顯式開啟事務(wù)
127.0.0.1:6379> MULTI
OK
# 給陀螺增加10元
127.0.0.1:6379(TX)> INCRBY tuoluo 10
QUEUED
# 給招財(cái)減少10元
127.0.0.1:6379(TX)> DECRBY zhaocai 10
QUEUED
# 執(zhí)行事務(wù)中的所有指令(提交事務(wù))
127.0.0.1:6379(TX)> EXEC
1) (integer) 110
2) (integer) 90

2.2.2 嵌套事務(wù)

Redis不支持嵌套事務(wù),多個(gè)MULTI命令和單個(gè)MULTI命令效果相同。

# 第一次開啟事務(wù)
127.0.0.1:6379> MULTI
OK
# 嘗試嵌套事務(wù)
127.0.0.1:6379(TX)> MULTI
(error) ERR MULTI calls can not be nested
# 仍然處于第一個(gè)事務(wù)當(dāng)中
127.0.0.1:6379(TX)>

2.2.3 放棄事務(wù)

如果開啟事務(wù)之后,中途后悔了怎么辦?調(diào)用DISCARD可以清空事務(wù)中的指令隊(duì)列,退出事務(wù)。

127.0.0.1:6379> MULTI
OK
# 在事務(wù)中調(diào)用DISCARD指令
127.0.0.1:6379(TX)> DISCARD
OK
# 會(huì)退出當(dāng)前事務(wù)
127.0.0.1:6379>

2.2.4 watch指令

假如我們?cè)谝粋€(gè)客戶端連接中開啟了事務(wù),另一個(gè)客戶端連接修改了這個(gè)事務(wù)涉及的變量值,將會(huì)怎樣?

client1開啟了一個(gè)轉(zhuǎn)賬的事務(wù),事務(wù)開始時(shí)招財(cái)和陀螺各自擁有100元,在執(zhí)行EXEC指令之前,client2將陀螺的余額添加了10元,此時(shí)執(zhí)行EXEC之后,陀螺最終的金額為120元,招財(cái)為90元。

很明顯,這種情況下存在數(shù)據(jù)安全問題。

為此Redis提供了WATCH的指令,該指令可以為Redis事務(wù)提供CAS樂觀鎖行為,即多個(gè)連接同時(shí)更新變量的時(shí)候,會(huì)和變量的初始值進(jìn)行比較,只在這個(gè)變量的值沒有被修改的情況下才會(huì)更新成新的值。

2.2.4.1 WATCH用法

對(duì)應(yīng)我們的案例,我們可以使用WATCH監(jiān)聽一個(gè)或多個(gè)key,如果開啟事務(wù)之前,至少有一個(gè)被監(jiān)視的key在EXEC執(zhí)行之前被修改了,那么整個(gè)事務(wù)都會(huì)被取消,直接返回nil(見下面的案例)。UNWATCH是WATCH的反操作。

2.2.4.2 CAS機(jī)制

CAS(Compare And Swap)比較并替換,是多并發(fā)時(shí)常用的一種樂觀鎖技術(shù)

CAS需要三個(gè)變量信息,分別是內(nèi)存位置(JAVA中的內(nèi)存地址,V),舊的預(yù)期值(A)和新值(B)。CAS執(zhí)行時(shí),當(dāng)且僅當(dāng)V和預(yù)期值A(chǔ)相等時(shí),更新V的值為新值B,否則不執(zhí)行更新。

3. 事務(wù)執(zhí)行出錯(cuò)怎么辦

事務(wù)執(zhí)行時(shí)可能遇到問題,按照發(fā)生的時(shí)機(jī)不同分為兩種:

  • 執(zhí)行EXEC之前
  • 執(zhí)行EXEC之后

3.1 執(zhí)行EXEC之前發(fā)生錯(cuò)誤

比如指令存在語法錯(cuò)誤(參數(shù)數(shù)量不對(duì),指令單詞拼錯(cuò))導(dǎo)致不能進(jìn)入commands隊(duì)列,這一步主要是編譯錯(cuò)誤,還未到運(yùn)行時(shí)。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> SET tuoluo
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> EXEC
(error) EXECABORT Transaction discarded because of previous errors.

這種情況下事務(wù)會(huì)執(zhí)行失敗,隊(duì)列中的所有指令都不會(huì)得到執(zhí)行。

3.2 執(zhí)行EXEC之后發(fā)生錯(cuò)誤

這種錯(cuò)誤往往是類型錯(cuò)誤,比如對(duì)String使用了Hash的命令,這是運(yùn)行時(shí)錯(cuò)誤,編譯期間不會(huì)出錯(cuò)

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> SET tuoluo 100
QUEUED
127.0.0.1:6379(TX)> LPOP tuoluo
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

我們發(fā)現(xiàn),SET tuoluo 100的命令居然執(zhí)行成功了,也就是在發(fā)生了運(yùn)行異常的情況下,錯(cuò)誤的指令不會(huì)被執(zhí)行,但是其他的命令不會(huì)受影響。

這種方式顯然不符合我們對(duì)原子性的定義,也就是Redis的事務(wù)無法實(shí)現(xiàn)原子性,無法保證數(shù)據(jù)一致。

針對(duì)這種缺陷,Redis官方也是做了說明的。

4. Redis事務(wù)為什么不支持回滾

引自Redis官方文檔。

為了方便大家理解,我翻譯一下就是:

  • 你們程序員的鍋,關(guān)我們Redis屁事兒!

Redis官方認(rèn)為,只有在命令語法錯(cuò)誤或者類型錯(cuò)誤的時(shí)候,Redis命令才會(huì)執(zhí)行失敗。而且他們認(rèn)為有這種錯(cuò)誤的語法一般也不會(huì)進(jìn)入到生產(chǎn)環(huán)境。而且不支持回滾可以使他們有更多時(shí)間玩兒Redis運(yùn)行得更簡單快捷。

這種說法多牛!如果出問題就是程序員的問題,寫錯(cuò)了還讓代碼進(jìn)入生產(chǎn)環(huán)境,那就是罪上加罪,你永遠(yuǎn)賴不著Redis官方。

這可能就是不推薦使用Redis事務(wù)的原因了吧,雞肋是一方面,萬一被官方打臉了呢?所以Redis事務(wù)的知識(shí)稍微了解一下就好,面試被問到能回到上來就可以了。


網(wǎng)站欄目:簡單聊一聊Redis事務(wù)
分享地址:http://www.dlmjj.cn/article/dhgspjs.html