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

Redis 事務(wù)那些事兒:實(shí)用技巧和避坑指南!

開發(fā) Redis
今天這篇文章,我想用最實(shí)在的語(yǔ)言,把 Redis 事務(wù)的本質(zhì)、用法和注意事項(xiàng)講清楚,幫你在實(shí)際開發(fā)中少踩坑。

一、為什么我們關(guān)心Redis事務(wù)?

在Java開發(fā)的日常工作中,Redis幾乎無處不在。你可能用它做緩存、排行榜、分布式鎖,甚至用它做輕量級(jí)的數(shù)據(jù)存儲(chǔ)。

但隨著業(yè)務(wù)復(fù)雜度提升,很多人都會(huì)遇到這樣的問題:

  • 多個(gè)Redis操作需要保證原子性,怎么做?
  • Redis的事務(wù)和MySQL事務(wù)一樣靠譜嗎?
  • WATCH、MULTI、EXEC這些命令到底怎么用?能不能防止并發(fā)下的數(shù)據(jù)不一致?

這些問題看似簡(jiǎn)單,實(shí)則暗藏不少坑。今天這篇文章,我想用最實(shí)在的語(yǔ)言,把Redis事務(wù)的本質(zhì)、用法和注意事項(xiàng)講清楚,幫你在實(shí)際開發(fā)中少踩坑。

二、Redis事務(wù)機(jī)制全解析

1. Redis到底支不支持事務(wù)?

結(jié)論先行:Redis支持事務(wù),但和MySQL事務(wù)完全不是一回事。

MySQL事務(wù)強(qiáng)調(diào)ACID(原子性、一致性、隔離性、持久性),而Redis的事務(wù)機(jī)制更像是“命令打包、順序執(zhí)行”,沒有復(fù)雜的隔離和回滾機(jī)制。

2. Redis事務(wù)的基本命令和用法

Redis事務(wù)的核心命令有四個(gè):MULTI、EXEC、DISCARD、WATCH。

(1) MULTI/EXEC:事務(wù)的開始與提交

  • MULTI:開啟事務(wù),后續(xù)命令進(jìn)入隊(duì)列
  • EXEC:提交事務(wù),隊(duì)列中的命令依次執(zhí)行

舉個(gè)例子:

# 1. 初始化庫(kù)存
127.0.0.1:6379> set a:stock 100
OK
127.0.0.1:6379> set b:stock 200
OK
# 2. 開啟事務(wù)
127.0.0.1:6379> multi
OK
# 3. 將a:stock減1
127.0.0.1:6379> decr a:stock
QUEUED
# 4. 將b:stock減1
127.0.0.1:6379> decr b:stock
QUEUED
# 5. 實(shí)際執(zhí)行事務(wù)
127.0.0.1:6379> exec
1) (integer) 99
2) (integer) 199
127.0.0.1:6379>

(2) DISCARD:放棄事務(wù)

如果在MULTI之后,發(fā)現(xiàn)有問題,可以用DISCARD放棄事務(wù),清空命令隊(duì)列。

(3) WATCH:樂觀鎖的實(shí)現(xiàn)

在并發(fā)場(chǎng)景下,單靠MULTI/EXEC還不夠。比如轉(zhuǎn)賬操作,兩個(gè)客戶端同時(shí)讀取余額,都判斷可以轉(zhuǎn)賬,結(jié)果都扣了錢,余額就出錯(cuò)了。

這時(shí)候可以用WATCH命令,類似樂觀鎖。WATCH會(huì)監(jiān)控指定的key,如果在事務(wù)提交前這些key被其他客戶端修改,EXEC會(huì)失敗,事務(wù)不會(huì)執(zhí)行。

示例:

127.0.0.1:6379> get a:stock
"99"
127.0.0.1:6379> watch a:stock
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decr a:stock
QUEUED
127.0.0.1:6379> decr b:stock
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>

如上所示,a:stock在EXEC前被其他客戶端修改,EXEC會(huì)返回null,表示事務(wù)失敗。

三、Redis事務(wù)的常見“坑”和注意事項(xiàng)

1. 沒有回滾機(jī)制

只要EXEC執(zhí)行,前面的命令就算后面有錯(cuò),也不會(huì)回滾。比如:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name tom
QUEUED
127.0.0.1:6379> incr name 
QUEUED
127.0.0.1:6379> set age 18
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
127.0.0.1:6379>
  • set name tom執(zhí)行成功。
  • incr name 執(zhí)行時(shí)報(bào)錯(cuò)(因?yàn)?name 是字符串,不能自增)。
  • set age 18依然會(huì)被執(zhí)行。

注意:Redis事務(wù)中,某條命令出錯(cuò)不會(huì)影響其他命令的執(zhí)行,也不會(huì)回滾。

那如果我們想實(shí)現(xiàn)回滾的效果怎么辦呢?

2. 如何用DISCARD修復(fù)?

如果你在MULTI之后發(fā)現(xiàn)命令寫錯(cuò)了,可以在EXEC之前執(zhí)行DISCARD,這樣所有已入隊(duì)的命令都不會(huì)被執(zhí)行,數(shù)據(jù)不會(huì)被修改。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set addr bj
QUEUED
127.0.0.1:6379> incr addr
QUEUED
127.0.0.1:6379> set code 110
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get addr
(nil)
127.0.0.1:6379>

執(zhí)行結(jié)果:

  • set addr bj、set code 110都不會(huì)被執(zhí)行。
  • 事務(wù)被徹底放棄,Redis狀態(tài)不會(huì)有任何變化。

注意點(diǎn):

  • 一旦執(zhí)行了EXEC,就無法再用DISCARD撤銷事務(wù),已經(jīng)執(zhí)行的命令不會(huì)回滾。
  • DISCARD只能在事務(wù)提交前使用,相當(dāng)于“撤銷”本次事務(wù)。

3. 沒有隔離性

Redis事務(wù)期間,其他客戶端依然可以操作相關(guān)key。WATCH只能監(jiān)控key本身的變化,不能保證更復(fù)雜的業(yè)務(wù)一致性。

比如你WATCH了a:stock,但b:stock被其他客戶端修改了,你的事務(wù)依然會(huì)執(zhí)行。

四、實(shí)用干貨:Redis事務(wù)的正確打開方式

(1) 能用原子命令就用原子命令

Redis本身很多命令就是原子的,比如INCR、DECR、SETNX等,優(yōu)先用這些。

(2) 事務(wù)只保證命令的“批量、順序、一次性”執(zhí)行

不保證命令之間的隔離和回滾。

(3) WATCH適合樂觀鎖場(chǎng)景

比如扣庫(kù)存、轉(zhuǎn)賬等,先WATCH關(guān)鍵key,判斷條件后再M(fèi)ULTI/EXEC。

(4) 復(fù)雜業(yè)務(wù)建議用Lua腳本

Lua腳本在Redis中是原子執(zhí)行的,可以實(shí)現(xiàn)更復(fù)雜的業(yè)務(wù)邏輯和回滾。

(5) 不要把Redis事務(wù)當(dāng)成數(shù)據(jù)庫(kù)事務(wù)用

Redis事務(wù)和MySQL事務(wù)完全不是一回事,不能指望它幫你兜底所有一致性問題。

五、Redis事務(wù)和ACID的對(duì)比

很多同學(xué)會(huì)問:Redis事務(wù)到底支持ACID的哪幾項(xiàng)?

(1) 原子性(Atomicity)

Redis事務(wù)只保證“命令隊(duì)列”整體的原子性,不保證單條命令的原子性。EXEC時(shí),要么所有命令都執(zhí)行,要么都不執(zhí)行(WATCH監(jiān)控失敗時(shí))。

(2) 一致性(Consistency)

Redis事務(wù)本身不保證數(shù)據(jù)的一致性,需要開發(fā)者自己保證。

(3) 隔離性(Isolation)

Redis事務(wù)沒有嚴(yán)格的隔離性,事務(wù)執(zhí)行期間,其他客戶端可以修改相關(guān)key。

(4) 持久性(Durability)

取決于Redis的持久化配置(RDB、AOF),和事務(wù)機(jī)制本身無關(guān)。

一句話總結(jié):Redis事務(wù)只保證“命令批量執(zhí)行的原子性”,不保證隔離和回滾。

六、面試高頻問答

(1) Redis事務(wù)和MySQL事務(wù)的區(qū)別?

  • MySQL事務(wù)支持ACID,Redis事務(wù)只保證命令批量執(zhí)行的原子性。
  • MySQL事務(wù)有回滾機(jī)制,Redis事務(wù)沒有。
  • MySQL事務(wù)有隔離級(jí)別,Redis事務(wù)沒有。

(2) Redis事務(wù)失敗會(huì)回滾嗎?

不會(huì)。只要EXEC執(zhí)行,前面的命令就算后面有錯(cuò),也不會(huì)回滾。

(3) WATCH命令的作用是什么?

實(shí)現(xiàn)樂觀鎖,監(jiān)控指定key,防止并發(fā)下的數(shù)據(jù)不一致。

(4) Redis事務(wù)適合哪些場(chǎng)景?

適合批量命令、簡(jiǎn)單樂觀鎖場(chǎng)景。不適合強(qiáng)一致性、復(fù)雜回滾的業(yè)務(wù)。

責(zé)任編輯:趙寧寧 來源: 程序員徐述
相關(guān)推薦

2009-09-04 10:27:28

Linux實(shí)用技巧linux操作系統(tǒng)linux

2022-03-23 09:18:10

Git技巧Linux

2009-12-21 15:50:39

2024-11-29 10:48:54

IDEA技巧Mac

2023-11-29 16:20:21

2009-01-03 09:34:30

ASP.NET.NET性能優(yōu)化

2011-04-08 15:40:01

Oracle認(rèn)證

2022-11-03 10:28:59

PandasSAC機(jī)制

2022-10-11 08:00:47

多線程開發(fā)技巧

2024-05-17 08:52:43

SQL實(shí)用技巧行列轉(zhuǎn)換

2021-02-26 00:46:11

CIO數(shù)據(jù)決策數(shù)字化轉(zhuǎn)型

2024-04-03 12:30:00

C++開發(fā)

2024-04-24 13:45:00

2010-10-08 15:44:17

vim

2019-12-22 23:10:19

LinuxSSH加密

2009-12-09 11:21:30

Linux實(shí)用技巧

2019-11-25 10:12:59

Python技巧工具

2010-09-14 10:41:24

DIV+CSS排版

2016-12-28 13:19:08

Android開發(fā)坑和小技巧

2020-08-26 07:37:25

Nacos微服務(wù)SpringBoot
點(diǎn)贊
收藏

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