偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

簡(jiǎn)單聊一聊Redis事務(wù)

開(kāi)發(fā) 前端
沒(méi)錯(cuò),Redis也有事務(wù)管理,但是功能很簡(jiǎn)單,在正式開(kāi)發(fā)中也并不推薦使用。但是面試中有可能會(huì)問(wèn)到,所以本文簡(jiǎn)單談一談Redis的事務(wù)。

沒(méi)錯(cuò),Redis也有事務(wù)管理,但是功能很簡(jiǎn)單,在正式開(kāi)發(fā)中也并不推薦使用。但是面試中有可能會(huì)問(wèn)到,所以本文簡(jiǎn)單談一談Redis的事務(wù)。

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

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

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

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

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

在涉及到多個(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è)簡(jiǎn)單的需求都沒(méi)辦法完美做到,至于為啥,接著往下看吧

2. 事務(wù)的用法

2.1 5個(gè)基本指令

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

  • MULTI
  • EXEC
  • DISCARD
  • WATCH
  • UNWATCH

2.2 案例演示

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

2.2.1 事務(wù)提交

我們首先為陀螺和招財(cái)初始化自己的金額;然后使用MULTI命令顯式開(kāi)啟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
# 顯式開(kāi)啟事務(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命令效果相同。

# 第一次開(kāi)啟事務(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ù)

如果開(kāi)啟事務(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è)客戶端連接中開(kāi)啟了事務(wù),另一個(gè)客戶端連接修改了這個(gè)事務(wù)涉及的變量值,將會(huì)怎樣?

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

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

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

2.2.4.1 WATCH用法

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

2.2.4.2 CAS機(jī)制

CAS(Compare And Swap)比較并替換,是多并發(fā)時(shí)常用的一種樂(lè)觀鎖技術(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í)可能遇到問(wèn)題,按照發(fā)生的時(shí)機(jī)不同分為兩種:

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

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

比如指令存在語(yǔ)法錯(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ò)誤往往是類(lèi)型錯(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ù)無(wú)法實(shí)現(xiàn)原子性,無(wú)法保證數(shù)據(jù)一致。

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

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

引自Redis官方文檔。

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

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

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

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

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

責(zé)任編輯:未麗燕 來(lái)源: 今日頭條
相關(guān)推薦

2018-01-10 14:13:04

測(cè)試矩陣API測(cè)試

2023-06-02 07:45:39

2022-05-12 23:19:15

Redis內(nèi)存碎片處理

2023-03-06 21:23:23

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

2021-08-11 09:37:11

Redis持久化磁盤(pán)

2022-05-18 16:35:43

Redis內(nèi)存運(yùn)維

2024-09-09 08:29:25

2018-06-07 13:17:12

契約測(cè)試單元測(cè)試API測(cè)試

2023-09-22 17:36:37

2021-01-28 22:31:33

分組密碼算法

2020-05-22 08:16:07

PONGPONXG-PON

2020-08-12 08:34:16

開(kāi)發(fā)安全We

2022-11-26 00:00:06

裝飾者模式Component

2022-10-08 11:33:56

邊緣計(jì)算云計(jì)算

2019-12-17 10:06:18

CDMA高通4G

2020-09-08 06:54:29

Java Gradle語(yǔ)言

2022-03-29 09:56:21

游戲版本運(yùn)營(yíng)

2021-01-01 09:01:05

前端組件化設(shè)計(jì)

2020-06-28 09:30:37

Linux內(nèi)存操作系統(tǒng)

2021-08-04 09:32:05

Typescript 技巧Partial
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)