溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

redis演練(3) redis事務(wù)管理

發(fā)布時(shí)間:2020-08-31 12:38:35 來源:網(wǎng)絡(luò) 閱讀:3192 作者:randy_shandong 欄目:數(shù)據(jù)庫(kù)

redis vs memcached。

redis與memcached對(duì)比,redis不僅適合做緩存,而且可以做存儲(chǔ),這就有點(diǎn)數(shù)據(jù)庫(kù)的影子了。說到數(shù)據(jù)庫(kù),事務(wù)是一個(gè)很重要的一個(gè)方面。

數(shù)據(jù)庫(kù)事務(wù)

(簡(jiǎn)稱:事務(wù))是數(shù)據(jù)庫(kù)管理系統(tǒng)執(zhí)行過程中的一個(gè)邏輯單位,由一個(gè)有限的數(shù)據(jù)庫(kù)操作序列構(gòu)成。

一個(gè)數(shù)據(jù)庫(kù)事務(wù)通常包含了一個(gè)序列的對(duì)數(shù)據(jù)庫(kù)的讀/寫操作。它的存在包含有以下兩個(gè)目的:
1.為數(shù)據(jù)庫(kù)操作序列提供了一個(gè)從失敗中恢復(fù)到正常狀態(tài)的方法,同時(shí)提供了數(shù)據(jù)庫(kù)即使在異常狀態(tài)下仍能保持一致性的方法。
2.當(dāng)多個(gè)應(yīng)用程序在并發(fā)訪問數(shù)據(jù)庫(kù)時(shí),可以在這些應(yīng)用程序之間提供一個(gè)隔離方法,以防止彼此的操作互相干擾。

事務(wù)約束

當(dāng)事務(wù)被提交給了DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng)),則DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng))需要確保該事務(wù)中的所有操作都成功完成且其結(jié)果被永久保存在數(shù)據(jù)庫(kù)中,如果事務(wù)中有的操作沒有成功完成,則事務(wù)中的所有操作都需要被回滾,回到事務(wù)執(zhí)行前的狀態(tài);同時(shí),該事務(wù)對(duì)數(shù)據(jù)庫(kù)或者其他事務(wù)的執(zhí)行無影響,所有的事務(wù)都好像在獨(dú)立的運(yùn)行。

通過事務(wù)的約束條件,可以總結(jié)出四個(gè)特點(diǎn)

原子性(Atomicity):事務(wù)作為一個(gè)整體被執(zhí)行,包含在其中的對(duì)數(shù)據(jù)庫(kù)的操作要么全部被執(zhí)行,要么都不執(zhí)行。
一致性(Consistency):事務(wù)應(yīng)確保數(shù)據(jù)庫(kù)的狀態(tài)從一個(gè)一致狀態(tài)轉(zhuǎn)變?yōu)榱硪粋€(gè)一致狀態(tài)。一致狀態(tài)的含義是數(shù)據(jù)庫(kù)中的數(shù)據(jù)應(yīng)滿足完整性約束
隔離性(Isolation):多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),一個(gè)事務(wù)的執(zhí)行不應(yīng)影響其他事務(wù)的執(zhí)行
持久性(Durability):已被提交的事務(wù)對(duì)數(shù)據(jù)庫(kù)的修改應(yīng)該永久保存在數(shù)據(jù)庫(kù)中

有興趣的更深了解事務(wù)相關(guān),可以關(guān)注下事務(wù)傳播屬性,事務(wù)隔離級(jí)別。

本文主要演練下redis對(duì)事務(wù)的支持效果。

1 相關(guān)命令

redis演練(3) redis事務(wù)管理

命令
作用
可用版本
時(shí)間復(fù)雜度返回值
WATCH key [key ...]

監(jiān)視一個(gè)(或多個(gè)) key ,如果在事務(wù)執(zhí)行之前這個(gè)(或這些) key 被其他命令所改動(dòng),那么事務(wù)將被打斷。


>= 2.2.0

O(1)


總是返回 OK


MULTI
標(biāo)記一個(gè)事務(wù)塊的開始>= 1.2.0O(1)總是返回 OK
EXEC

執(zhí)行所有事務(wù)塊內(nèi)的命令。

假如某個(gè)(或某些) key 正處于 WATCH 命令的監(jiān)視之下,且事務(wù)塊中有和這個(gè)(或這些) key 相關(guān)的命令,那么 EXEC 命令只在這個(gè)(或這些) key 沒有被其他命令所改動(dòng)的情況下執(zhí)行并生效,否則該事務(wù)被打斷(abort)。

 >= 1.2.0
事務(wù)塊內(nèi)所有命令的時(shí)間復(fù)雜度的總和事務(wù)塊內(nèi)所有命令的返回值,按命令執(zhí)行的先后順序排列。
    當(dāng)操作被打斷時(shí),返回空值 nil 。


DISCARD取消事務(wù),放棄執(zhí)行事務(wù)塊內(nèi)的所有命令。

如果正在使用 WATCH 命令監(jiān)視某個(gè)(或某些) key,那么取消所有監(jiān)視,等同于執(zhí)行命令 UNWATCH 。
>= 2.0.0O(1)總是返回 OK 。
UNWATCH
取消 WATCH 命令對(duì)所有 key 的監(jiān)視。

如果在執(zhí)行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被執(zhí)行了的話,那么就不需要再執(zhí)行 UNWATCH 了。

因?yàn)?EXEC 命令會(huì)執(zhí)行事務(wù),因此 WATCH 命令的效果已經(jīng)產(chǎn)生了;而 DISCARD 命令在取消事務(wù)的同時(shí)也會(huì)取消所有對(duì) key 的監(jiān)視,因此這兩個(gè)命令執(zhí)行之后,就沒有必要執(zhí)行 UNWATCH 了。
>= 2.2.0O(1)總是 OK 。

上面,自己僅僅進(jìn)行了整理,沒什么好說的。重點(diǎn)是演練

2.命令演練

2.1MULTI ,起聲明事務(wù)的意思。表示“下面的命令,打個(gè)包做個(gè)整體”但不絕對(duì)。

127.0.0.1:6379> incr bar
(integer) 1
127.0.0.1:6379> incr foo
(integer) 1
#事務(wù)開始
127.0.0.1:6379> multi
OK
#發(fā)出的命令,直接返回QUEUED,放入隊(duì)列,不立即執(zhí)行
127.0.0.1:6379> incr bar
QUEUED
127.0.0.1:6379> incr foo
QUEUED
#執(zhí)行所有事務(wù)塊內(nèi)的命令
127.0.0.1:6379> exec
1) (integer) 2
2) (integer) 2

#演示語法出錯(cuò)情況,直接停止事務(wù)
127.0.0.1:6379> incr bar
QUEUED
127.0.0.1:6379> incrbar
(error) ERR unknown command 'incrbar'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
#事務(wù)不允許連續(xù)聲明
127.0.0.1:6379> multi
OK
127.0.0.1:6379> multi
(error) ERR MULTI calls can not be nested

#演示命令參數(shù)不匹配,部分成功
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr bar
QUEUED
127.0.0.1:6379> lpush bar "value2"
QUEUED
127.0.0.1:6379> exec
1) (integer) 2
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

結(jié)論

multi:不支持嵌套

redis對(duì)事務(wù)的支持,不嚴(yán)謹(jǐn)。不太符合ACID中的原子性。

Redis 在事務(wù)失敗時(shí)不進(jìn)行回滾,而是繼續(xù)執(zhí)行余下的命令”

如果你有使用關(guān)系式數(shù)據(jù)庫(kù)的經(jīng)驗(yàn), 那么 “Redis 在事務(wù)失敗時(shí)不進(jìn)行回滾,而是繼續(xù)執(zhí)行余下的命令”這種做法可能會(huì)讓你覺得有點(diǎn)奇怪。

以下是這種做法的優(yōu)點(diǎn):

  • Redis 命令只會(huì)因?yàn)殄e(cuò)誤的語法而失?。ú⑶疫@些問題不能在入隊(duì)時(shí)發(fā)現(xiàn)),或是命令用在了錯(cuò)誤類型的鍵上面:這也就是說,從實(shí)用性的角度來說,失敗的命令是由編程錯(cuò)誤造成的,而這些錯(cuò)誤應(yīng)該在開發(fā)的過程中被發(fā)現(xiàn),而不應(yīng)該出現(xiàn)在生產(chǎn)環(huán)境中。

  • 因?yàn)椴恍枰獙?duì)回滾進(jìn)行支持,所以 Redis 的內(nèi)部可以保持簡(jiǎn)單且快速。


2.discard,"丟棄”意思。表示“上面的命令,統(tǒng)統(tǒng)都不要了”有點(diǎn)rollback的影子,但又不是。discard的意思,是把隊(duì)列中的命令舍棄掉,這時(shí)候還沒有發(fā)出命令。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> discard
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr bar
QUEUED
127.0.0.1:6379> incr foo
QUEUED
127.0.0.1:6379> discard
OK


2.1 WATCH :含義“監(jiān)視”。表示“這是我的菜,其他人靠邊站”。

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
#watch命令不能在事務(wù)里出現(xiàn),否則ERR
127.0.0.1:6379> watch bar
(error) ERR WATCH inside MULTI is not allowed

#監(jiān)控bar,bar不再是隨便的key了,不允許隨便修改了。
127.0.0.1:6379> watch bar
OK
#事務(wù)之前,沒有修改bar,事務(wù)成功
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr bar
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
#exec,將watch 打斷,重新watch
127.0.0.1:6379> watch bar
OK
##事務(wù)之前,修改bar,事務(wù)失敗
127.0.0.1:6379> incr bar
(integer) 2
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr bar
QUEUED
127.0.0.1:6379> exec
(nil)
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI