最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Redis 事務(wù) (事務(wù)模式 VS Lua 腳本)

2023-04-09 09:02 作者:Cpp程序員  | 我要投稿

1 事務(wù)原理

Redis 的事務(wù)包含如下命令:

序號命令及描述1MULTI 標(biāo)記一個事務(wù)塊的開始。2EXEC 執(zhí)行所有事務(wù)塊內(nèi)的命令。3DISCARD 取消事務(wù),放棄執(zhí)行事務(wù)塊內(nèi)的所有命令。4WATCH key [key ...] 監(jiān)視一個(或多個) key ,如果在事務(wù)執(zhí)行之前這個(或這些) key 被其他命令所改動,那么事務(wù)將被打斷。5UNWATCH 取消 WATCH 命令對所有 key 的監(jiān)視。

事務(wù)包含三個階段:

  1. 事務(wù)開啟,使用 MULTI , 該命令標(biāo)志著執(zhí)行該命令的客戶端從非事務(wù)狀態(tài)切換至事務(wù)狀態(tài) ;

  2. 命令入隊,MULTI 開啟事務(wù)之后,客戶端的命令并不會被立即執(zhí)行,而是放入一個事務(wù)隊列 ;

  3. 執(zhí)行事務(wù)或者丟棄。如果收到 EXEC 的命令,事務(wù)隊列里的命令將會被執(zhí)行 ,如果是 DISCARD 則事務(wù)被丟棄。

下面展示一個事務(wù)的例子。

redis> MULTI OK redis> SET msg "hello world" QUEUED redis> GET msg QUEUED redis> EXEC 1) OK 1) hello world

這里有一個疑問?在開啟事務(wù)的時候,Redis key 可以被修改嗎?

在事務(wù)執(zhí)行 EXEC 命令之前 ,Redis key 依然可以被修改。

在事務(wù)開啟之前,我們可以 watch 命令監(jiān)聽 Redis key 。在事務(wù)執(zhí)行之前,我們修改 key 值 ,事務(wù)執(zhí)行失敗,返回?nil?。

通過上面的例子,watch 命令可以實現(xiàn)類似樂觀鎖的效果?。

2 事務(wù)的ACID

2.1 原子性

原子性是指:一個事務(wù)中的所有操作,或者全部完成,或者全部不完成,不會結(jié)束在中間某個環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯誤,會被回滾到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣。

第一個例子:

在執(zhí)行 EXEC 命令前,客戶端發(fā)送的操作命令錯誤,比如:語法錯誤或者使用了不存在的命令。

redis> MULTI OK redis> SET msg "other msg" QUEUED redis> wrongcommand ?### 故意寫錯誤的命令 (error) ERR unknown command 'wrongcommand' redis> EXEC (error) EXECABORT Transaction discarded because of previous errors. redis> GET msg "hello world"

在這個例子中,我們使用了不存在的命令,導(dǎo)致入隊失敗,整個事務(wù)都將無法執(zhí)行 。

第二個例子:

事務(wù)操作入隊時,命令和操作的數(shù)據(jù)類型不匹配 ,入隊列正常,但執(zhí)行 EXEC 命令異常 。

redis> MULTI ? OK redis> SET msg "other msg" QUEUED redis> SET mystring "I am a string" QUEUED redis> HMSET mystring name ?"test" QUEUED redis> SET msg "after" QUEUED redis> EXEC 1) OK 2) OK 3) (error) WRONGTYPE Operation against a key holding the wrong kind of value 4) OK redis> GET msg "after"

這個例子里,Redis 在執(zhí)行 EXEC 命令時,如果出現(xiàn)了錯誤,Redis 不會終止其它命令的執(zhí)行,事務(wù)也不會因為某個命令執(zhí)行失敗而回滾 。

綜上,我對 Redis 事務(wù)原子性的理解如下:

  1. 命令入隊時報錯, 會放棄事務(wù)執(zhí)行,保證原子性;

  2. 命令入隊時正常,執(zhí)行 EXEC 命令后報錯,不保證原子性;

也就是:Redis 事務(wù)在特定條件下,才具備一定的原子性?。

2.2 隔離性

數(shù)據(jù)庫的隔離性是指:數(shù)據(jù)庫允許多個并發(fā)事務(wù)同時對其數(shù)據(jù)進(jìn)行讀寫和修改的能力,隔離性可以防止多個事務(wù)并發(fā)執(zhí)行時由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。

事務(wù)隔離分為不同級別 ,分別是:

  • 未提交讀(read uncommitted)

  • 提交讀(read committed)

  • 可重復(fù)讀(repeatable read)

  • 串行化(serializable)

首先,需要明確一點:Redis 并沒有事務(wù)隔離級別的概念。這里我們討論 Redis 的隔離性是指:并發(fā)場景下,事務(wù)之間是否可以做到互不干擾

我們可以將事務(wù)執(zhí)行可以分為?EXEC 命令執(zhí)行前和?EXEC 命令執(zhí)行后兩個階段,分開討論。

  1. EXEC 命令執(zhí)行前

在事務(wù)原理這一小節(jié),我們發(fā)現(xiàn)在事務(wù)執(zhí)行之前 ,Redis key 依然可以被修改。此時,可以使用?WATCH 機制來實現(xiàn)樂觀鎖的效果。

  1. EXEC 命令執(zhí)行后

因為 Redis 是單線程執(zhí)行操作命令, EXEC 命令執(zhí)行后,Redis 會保證命令隊列中的所有命令執(zhí)行完 。 這樣就可以保證事務(wù)的隔離性。

2.3 持久性

數(shù)據(jù)庫的持久性是指 :事務(wù)處理結(jié)束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會丟失。

Redis 的數(shù)據(jù)是否持久化取決于 Redis 的持久化配置模式 。

  1. 沒有配置 RDB 或者 AOF ,事務(wù)的持久性無法保證;

  2. 使用了 RDB模式,在一個事務(wù)執(zhí)行后,下一次的 RDB 快照還未執(zhí)行前,如果發(fā)生了實例宕機,事務(wù)的持久性同樣無法保證;

  3. 使用了 AOF 模式;AOF 模式的三種配置選項 no 、everysec 都會存在數(shù)據(jù)丟失的情況 。always 可以保證事務(wù)的持久性,但因為性能太差,在生產(chǎn)環(huán)境一般不推薦使用。

綜上,redis 事務(wù)的持久性是無法保證的?。

2.4 一致性

一致性的概念一直很讓人困惑,在我搜尋的資料里,有兩類不同的定義。

  1. 維基百科

我們先看下維基百科上一致性的定義:

Consistency ensures that a transaction can only bring the database from one valid state to another, maintaining database invariants: any data written to the database must be valid according to all defined rules, including constraints, cascades, triggers, and any combination thereof. This prevents database corruption by an illegal transaction, but does not guarantee that a transaction is correct. Referential integrity guarantees the primary key – foreign key relationship.

在這段文字里,一致性的核心是“約束”,“any data written to the database must be valid according to all defined rules?”。

如何理解約束?這里引用知乎問題?如何理解數(shù)據(jù)庫的內(nèi)部一致性和外部一致性,螞蟻金服 OceanBase 研發(fā)專家韓富晟回答的一段話:

“約束”由數(shù)據(jù)庫的使用者告訴數(shù)據(jù)庫,使用者要求數(shù)據(jù)一定符合這樣或者那樣的約束。當(dāng)數(shù)據(jù)發(fā)生修改時,數(shù)據(jù)庫會檢查數(shù)據(jù)是否還符合約束條件,如果約束條件不再被滿足,那么修改操作不會發(fā)生。

關(guān)系數(shù)據(jù)庫最常見的兩類約束是“唯一性約束”和“完整性約束”,表格中定義的主鍵和唯一鍵都保證了指定的數(shù)據(jù)項絕不會出現(xiàn)重復(fù),表格之間定義的參照完整性也保證了同一個屬性在不同表格中的一致性。

“ Consistency in ACID ”是如此的好用,以至于已經(jīng)融化在大部分使用者的血液里了,使用者會在表格設(shè)計的時候自覺的加上需要的約束條件,數(shù)據(jù)庫也會嚴(yán)格的執(zhí)行這個約束條件。

所以事務(wù)的一致性和預(yù)先定義的約束有關(guān),保證了約束即保證了一致性。

我們細(xì)細(xì)品一品這句話:?This prevents database corruption by an illegal transaction, but does not guarantee that a transaction is correct。

寫到這里可能大家還是有點模糊,我們舉經(jīng)典轉(zhuǎn)賬的案例。

我們開啟一個事務(wù),張三和李四賬號上的初始余額都是1000元,并且余額字段沒有任何約束。張三給李四轉(zhuǎn)賬1200元。張三的余額更新為 -200 , 李四的余額更新為2200。

從應(yīng)用層面來看,這個事務(wù)明顯不合法,因為現(xiàn)實場景中,用戶余額不可能小于 0 , 但是它完全遵循數(shù)據(jù)庫的約束,所以從數(shù)據(jù)庫層面來看,這個事務(wù)依然保證了一致性。

Redis 的事務(wù)一致性是指:Redis 事務(wù)在執(zhí)行過程中符合數(shù)據(jù)庫的約束,沒有包含非法或者無效的錯誤數(shù)據(jù)。


Redis 事務(wù) (事務(wù)模式 VS Lua 腳本)的評論 (共 條)

分享到微博請遵守國家法律
郴州市| 当涂县| 深圳市| 揭东县| 多伦县| 绿春县| 永兴县| 醴陵市| 澄城县| 沙河市| 边坝县| 南涧| 固镇县| 合水县| 河东区| 延川县| 中西区| 连南| 寿阳县| 麻栗坡县| 沙湾县| 阜新| 武威市| 绥德县| 安多县| 平塘县| 扶绥县| 咸宁市| 济南市| 启东市| 上栗县| 兴和县| 新化县| 绿春县| 兰州市| 嘉鱼县| 沾化县| 衡水市| 新沂市| 布尔津县| 马山县|