自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

簡單聊一聊Redis事務(wù)

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

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

通過這篇文章,你會了解

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

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

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

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

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

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

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

2. 事務(wù)的用法

2.1 5個基本指令

Redis提供了以下5個基本指令,先混個眼熟就行,接下來在案例中進(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ā)送多個指令,Redis不會立刻執(zhí)行這些命令,而是將這些指令依次放入當(dāng)前事務(wù)的指令隊(duì)列中;EXEC被調(diào)用后,所有的命令才會被依次執(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ù),多個MULTI命令和單個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
# 仍然處于第一個事務(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
# 會退出當(dāng)前事務(wù)
127.0.0.1:6379>

2.2.4 watch指令

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

client1開啟了一個轉(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樂觀鎖行為,即多個連接同時(shí)更新變量的時(shí)候,會和變量的初始值進(jìn)行比較,只在這個變量的值沒有被修改的情況下才會更新成新的值。

2.2.4.1 WATCH用法

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

2.2.4.2 CAS機(jī)制

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

CAS需要三個變量信息,分別是內(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í)行出錯怎么辦

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

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

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

比如指令存在語法錯誤(參數(shù)數(shù)量不對,指令單詞拼錯)導(dǎo)致不能進(jìn)入commands隊(duì)列,這一步主要是編譯錯誤,還未到運(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ù)會執(zhí)行失敗,隊(duì)列中的所有指令都不會得到執(zhí)行。

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

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

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)行異常的情況下,錯誤的指令不會被執(zhí)行,但是其他的命令不會受影響。

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

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

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

引自Redis官方文檔。

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

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

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

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

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

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

2018-01-10 14:13:04

測試矩陣API測試

2023-06-02 07:45:39

2022-05-12 23:19:15

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

2023-03-06 21:23:23

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

2024-09-09 08:29:25

2022-05-18 16:35:43

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

2021-08-11 09:37:11

Redis持久化磁盤

2021-01-28 22:31:33

分組密碼算法

2023-09-22 17:36:37

2020-05-22 08:16:07

PONGPONXG-PON

2018-06-07 13:17:12

契約測試單元測試API測試

2021-08-04 09:32:05

Typescript 技巧Partial

2022-08-08 08:25:21

Javajar 文件

2022-11-01 08:46:20

責(zé)任鏈模式對象

2018-11-29 09:13:47

CPU中斷控制器

2019-02-13 14:15:59

Linux版本Fedora

2021-01-29 08:32:21

數(shù)據(jù)結(jié)構(gòu)數(shù)組

2021-02-06 08:34:49

函數(shù)memoize文檔

2023-05-15 08:38:58

模板方法模式

2020-10-15 06:56:51

MySQL排序
點(diǎn)贊
收藏

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