探索Redis設(shè)計(jì)與實(shí)現(xiàn)14:Redis事務(wù)淺析與ACID特性介紹

本文轉(zhuǎn)自互聯(lián)網(wǎng)

本系列文章將整理到我在GitHub上的《Java面試指南》倉(cāng)庫(kù),更多精彩內(nèi)容請(qǐng)到我的倉(cāng)庫(kù)里查看

https://github.com/h2pl/Java-Tutorial

喜歡的話麻煩點(diǎn)下Star哈

文章首發(fā)于我的個(gè)人博客:

www.how2playlife.com

本文是微信公眾號(hào)【Java技術(shù)江湖】的《探索Redis設(shè)計(jì)與實(shí)現(xiàn)》其中一篇,本文部分內(nèi)容來(lái)源于網(wǎng)絡(luò),為了把本文主題講得清晰透徹,也整合了很多我認(rèn)為不錯(cuò)的技術(shù)博客內(nèi)容,引用其中了一些比較好的博客文章,如有侵權(quán),請(qǐng)聯(lián)系作者。

該系列博文會(huì)告訴你如何從入門(mén)到進(jìn)階,Redis基本的使用方法,Redis的基本數(shù)據(jù)結(jié)構(gòu),以及一些進(jìn)階的使用方法,同時(shí)也需要進(jìn)一步了解Redis的底層數(shù)據(jù)結(jié)構(gòu),再接著,還會(huì)帶來(lái)Redis主從復(fù)制、集群、分布式鎖等方面的相關(guān)內(nèi)容,以及作為緩存的一些使用方法和注意事項(xiàng),以便讓你更完整地了解整個(gè)Redis相關(guān)的技術(shù)體系,形成自己的知識(shí)框架。

如果對(duì)本系列文章有什么建議,或者是有什么疑問(wèn)的話,也可以關(guān)注公眾號(hào)【Java技術(shù)江湖】聯(lián)系作者,歡迎你參與本系列博文的創(chuàng)作和修訂。

事務(wù)

MULTI 、 EXECDISCARDWATCH 是 Redis 事務(wù)相關(guān)的命令。事務(wù)可以一次執(zhí)行多個(gè)命令, 并且?guī)в幸韵聝蓚€(gè)重要的保證:

  • 事務(wù)是一個(gè)單獨(dú)的隔離操作:事務(wù)中的所有命令都會(huì)序列化、按順序地執(zhí)行。事務(wù)在執(zhí)行的過(guò)程中,不會(huì)被其他客戶端發(fā)送來(lái)的命令請(qǐng)求所打斷。

  • 事務(wù)是一個(gè)原子操作:事務(wù)中的命令要么全部被執(zhí)行,要么全部都不執(zhí)行。

EXEC 命令負(fù)責(zé)觸發(fā)并執(zhí)行事務(wù)中的所有命令:

  • 如果客戶端在使用 MULTI 開(kāi)啟了一個(gè)事務(wù)之后,卻因?yàn)閿嗑€而沒(méi)有成功執(zhí)行 EXEC ,那么事務(wù)中的所有命令都不會(huì)被執(zhí)行。
  • 另一方面,如果客戶端成功在開(kāi)啟事務(wù)之后執(zhí)行 EXEC ,那么事務(wù)中的所有命令都會(huì)被執(zhí)行。

當(dāng)使用 AOF 方式做持久化的時(shí)候, Redis 會(huì)使用單個(gè) write(2) 命令將事務(wù)寫(xiě)入到磁盤(pán)中。

然而,如果 Redis 服務(wù)器因?yàn)槟承┰虮还芾韱T殺死,或者遇上某種硬件故障,那么可能只有部分事務(wù)命令會(huì)被成功寫(xiě)入到磁盤(pán)中。

如果 Redis 在重新啟動(dòng)時(shí)發(fā)現(xiàn) AOF 文件出了這樣的問(wèn)題,那么它會(huì)退出,并匯報(bào)一個(gè)錯(cuò)誤。

使用redis-check-aof程序可以修復(fù)這一問(wèn)題:它會(huì)移除 AOF 文件中不完整事務(wù)的信息,確保服務(wù)器可以順利啟動(dòng)。

從 2.2 版本開(kāi)始,Redis 還可以通過(guò)樂(lè)觀鎖(optimistic lock)實(shí)現(xiàn) CAS (check-and-set)操作,具體信息請(qǐng)參考文檔的后半部分。

用法

MULTI 命令用于開(kāi)啟一個(gè)事務(wù),它總是返回 OK 。 MULTI 執(zhí)行之后, 客戶端可以繼續(xù)向服務(wù)器發(fā)送任意多條命令, 這些命令不會(huì)立即被執(zhí)行, 而是被放到一個(gè)隊(duì)列中, 當(dāng) EXEC命令被調(diào)用時(shí), 所有隊(duì)列中的命令才會(huì)被執(zhí)行。

另一方面, 通過(guò)調(diào)用 DISCARD , 客戶端可以清空事務(wù)隊(duì)列, 并放棄執(zhí)行事務(wù)。

以下是一個(gè)事務(wù)例子, 它原子地增加了 foobar 兩個(gè)鍵的值:

> MULTIOK> INCR fooQUEUED> INCR barQUEUED> EXEC1) (integer) 12) (integer) 1

EXEC 命令的回復(fù)是一個(gè)數(shù)組, 數(shù)組中的每個(gè)元素都是執(zhí)行事務(wù)中的命令所產(chǎn)生的回復(fù)。 其中, 回復(fù)元素的先后順序和命令發(fā)送的先后順序一致。

當(dāng)客戶端處于事務(wù)狀態(tài)時(shí), 所有傳入的命令都會(huì)返回一個(gè)內(nèi)容為 QUEUED 的狀態(tài)回復(fù)(status reply), 這些被入隊(duì)的命令將在 EXEC 命令被調(diào)用時(shí)執(zhí)行。

事務(wù)中的錯(cuò)誤

使用事務(wù)時(shí)可能會(huì)遇上以下兩種錯(cuò)誤:

  • 事務(wù)在執(zhí)行 EXEC 之前,入隊(duì)的命令可能會(huì)出錯(cuò)。比如說(shuō),命令可能會(huì)產(chǎn)生語(yǔ)法錯(cuò)誤(參數(shù)數(shù)量錯(cuò)誤,參數(shù)名錯(cuò)誤,等等),或者其他更嚴(yán)重的錯(cuò)誤,比如內(nèi)存不足(如果服務(wù)器使用 maxmemory 設(shè)置了最大內(nèi)存限制的話)。
  • 命令可能在 EXEC 調(diào)用之后失敗。舉個(gè)例子,事務(wù)中的命令可能處理了錯(cuò)誤類(lèi)型的鍵,比如將列表命令用在了字符串鍵上面,諸如此類(lèi)。

對(duì)于發(fā)生在 EXEC 執(zhí)行之前的錯(cuò)誤,客戶端以前的做法是檢查命令入隊(duì)所得的返回值:如果命令入隊(duì)時(shí)返回 QUEUED ,那么入隊(duì)成功;否則,就是入隊(duì)失敗。如果有命令在入隊(duì)時(shí)失敗,那么大部分客戶端都會(huì)停止并取消這個(gè)事務(wù)。

不過(guò),從 Redis 2.6.5 開(kāi)始,服務(wù)器會(huì)對(duì)命令入隊(duì)失敗的情況進(jìn)行記錄,并在客戶端調(diào)用 EXEC 命令時(shí),拒絕執(zhí)行并自動(dòng)放棄這個(gè)事務(wù)。

在 Redis 2.6.5 以前, Redis 只執(zhí)行事務(wù)中那些入隊(duì)成功的命令,而忽略那些入隊(duì)失敗的命令。 而新的處理方式則使得在流水線(pipeline)中包含事務(wù)變得簡(jiǎn)單,因?yàn)榘l(fā)送事務(wù)和讀取事務(wù)的回復(fù)都只需要和服務(wù)器進(jìn)行一次通訊。

至于那些在 EXEC 命令執(zhí)行之后所產(chǎn)生的錯(cuò)誤, 并沒(méi)有對(duì)它們進(jìn)行特別處理: 即使事務(wù)中有某個(gè)/某些命令在執(zhí)行時(shí)產(chǎn)生了錯(cuò)誤, 事務(wù)中的其他命令仍然會(huì)繼續(xù)執(zhí)行。

從協(xié)議的角度來(lái)看這個(gè)問(wèn)題,會(huì)更容易理解一些。 以下例子中, LPOP 命令的執(zhí)行將出錯(cuò), 盡管調(diào)用它的語(yǔ)法是正確的:

Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.MULTI+OKSET a 3abc+QUEUEDLPOP a+QUEUEDEXEC*2+OK-ERR Operation against a key holding the wrong kind of value

EXEC 返回兩條bulk-string-reply: 第一條是 OK ,而第二條是 -ERR 。 至于怎樣用合適的方法來(lái)表示事務(wù)中的錯(cuò)誤, 則是由客戶端自己決定的。

最重要的是記住這樣一條, 即使事務(wù)中有某條/某些命令執(zhí)行失敗了, 事務(wù)隊(duì)列中的其他命令仍然會(huì)繼續(xù)執(zhí)行 —— Redis 不會(huì)停止執(zhí)行事務(wù)中的命令。

以下例子展示的是另一種情況, 當(dāng)命令在入隊(duì)時(shí)產(chǎn)生錯(cuò)誤, 錯(cuò)誤會(huì)立即被返回給客戶端:

MULTI+OKINCR a b c-ERR wrong number of arguments for 'incr' command

因?yàn)檎{(diào)用 INCR 命令的參數(shù)格式不正確, 所以這個(gè) INCR 命令入隊(duì)失敗。

為什么 Redis 不支持回滾(roll back)

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

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

  • Redis 命令只會(huì)因?yàn)殄e(cuò)誤的語(yǔ)法而失?。ú⑶疫@些問(wèn)題不能在入隊(duì)時(shí)發(fā)現(xiàn)),或是命令用在了錯(cuò)誤類(lèi)型的鍵上面:這也就是說(shuō),從實(shí)用性的角度來(lái)說(shuō),失敗的命令是由編程錯(cuò)誤造成的,而這些錯(cuò)誤應(yīng)該在開(kāi)發(fā)的過(guò)程中被發(fā)現(xiàn),而不應(yīng)該出現(xiàn)在生產(chǎn)環(huán)境中。
  • 因?yàn)椴恍枰獙?duì)回滾進(jìn)行支持,所以 Redis 的內(nèi)部可以保持簡(jiǎn)單且快速。

有種觀點(diǎn)認(rèn)為 Redis 處理事務(wù)的做法會(huì)產(chǎn)生 bug , 然而需要注意的是, 在通常情況下, 回滾并不能解決編程錯(cuò)誤帶來(lái)的問(wèn)題。 舉個(gè)例子, 如果你本來(lái)想通過(guò) INCR 命令將鍵的值加上 1 , 卻不小心加上了 2 , 又或者對(duì)錯(cuò)誤類(lèi)型的鍵執(zhí)行了 INCR, 回滾是沒(méi)有辦法處理這些情況的。

放棄事務(wù)

當(dāng)執(zhí)行 DISCARD 命令時(shí), 事務(wù)會(huì)被放棄, 事務(wù)隊(duì)列會(huì)被清空, 并且客戶端會(huì)從事務(wù)狀態(tài)中退出:

> SET foo 1OK> MULTIOK> INCR fooQUEUED> DISCARDOK> GET foo"1"

使用 check-and-set 操作實(shí)現(xiàn)樂(lè)觀鎖

WATCH 命令可以為 Redis 事務(wù)提供 check-and-set (CAS)行為。

WATCH 的鍵會(huì)被監(jiān)視,并會(huì)發(fā)覺(jué)這些鍵是否被改動(dòng)過(guò)了。 如果有至少一個(gè)被監(jiān)視的鍵在 EXEC 執(zhí)行之前被修改了, 那么整個(gè)事務(wù)都會(huì)被取消, EXEC 返回nil-reply來(lái)表示事務(wù)已經(jīng)失敗。

舉個(gè)例子, 假設(shè)我們需要原子性地為某個(gè)值進(jìn)行增 1 操作(假設(shè) INCR 不存在)。

首先我們可能會(huì)這樣做:

val = GET mykeyval = val + 1SET mykey $val

上面的這個(gè)實(shí)現(xiàn)在只有一個(gè)客戶端的時(shí)候可以執(zhí)行得很好。 但是, 當(dāng)多個(gè)客戶端同時(shí)對(duì)同一個(gè)鍵進(jìn)行這樣的操作時(shí), 就會(huì)產(chǎn)生競(jìng)爭(zhēng)條件。舉個(gè)例子, 如果客戶端 A 和 B 都讀取了鍵原來(lái)的值, 比如 10 , 那么兩個(gè)客戶端都會(huì)將鍵的值設(shè)為 11 , 但正確的結(jié)果應(yīng)該是 12 才對(duì)。

有了 WATCH , 我們就可以輕松地解決這類(lèi)問(wèn)題了:

WATCH mykeyval = GET mykeyval = val + 1MULTISET mykey $valEXEC

使用上面的代碼, 如果在 WATCH 執(zhí)行之后, EXEC 執(zhí)行之前, 有其他客戶端修改了 mykey 的值, 那么當(dāng)前客戶端的事務(wù)就會(huì)失敗。 程序需要做的, 就是不斷重試這個(gè)操作, 直到?jīng)]有發(fā)生碰撞為止。

這種形式的鎖被稱(chēng)作樂(lè)觀鎖, 它是一種非常強(qiáng)大的鎖機(jī)制。 并且因?yàn)榇蠖鄶?shù)情況下, 不同的客戶端會(huì)訪問(wèn)不同的鍵, 碰撞的情況一般都很少, 所以通常并不需要進(jìn)行重試。

了解 WATCH

WATCH 使得 EXEC 命令需要有條件地執(zhí)行: 事務(wù)只能在所有被監(jiān)視鍵都沒(méi)有被修改的前提下執(zhí)行, 如果這個(gè)前提不能滿足的話,事務(wù)就不會(huì)被執(zhí)行。 了解更多->

WATCH 命令可以被調(diào)用多次。 對(duì)鍵的監(jiān)視從 WATCH 執(zhí)行之后開(kāi)始生效, 直到調(diào)用 EXEC 為止。

用戶還可以在單個(gè) WATCH 命令中監(jiān)視任意多個(gè)鍵, 就像這樣:

redis> WATCH key1 key2 key3OK

當(dāng) EXEC 被調(diào)用時(shí), 不管事務(wù)是否成功執(zhí)行, 對(duì)所有鍵的監(jiān)視都會(huì)被取消。

另外, 當(dāng)客戶端斷開(kāi)連接時(shí), 該客戶端對(duì)鍵的監(jiān)視也會(huì)被取消。

使用無(wú)參數(shù)的 UNWATCH 命令可以手動(dòng)取消對(duì)所有鍵的監(jiān)視。 對(duì)于一些需要改動(dòng)多個(gè)鍵的事務(wù), 有時(shí)候程序需要同時(shí)對(duì)多個(gè)鍵進(jìn)行加鎖, 然后檢查這些鍵的當(dāng)前值是否符合程序的要求。 當(dāng)值達(dá)不到要求時(shí), 就可以使用 UNWATCH 命令來(lái)取消目前對(duì)鍵的監(jiān)視, 中途放棄這個(gè)事務(wù), 并等待事務(wù)的下次嘗試。

使用 WATCH 實(shí)現(xiàn) ZPOP

WATCH 可以用于創(chuàng)建 Redis 沒(méi)有內(nèi)置的原子操作。舉個(gè)例子, 以下代碼實(shí)現(xiàn)了原創(chuàng)的 ZPOP 命令, 它可以原子地彈出有序集合中分值(score)最小的元素:

WATCH zsetelement = ZRANGE zset 0 0MULTIZREM zset elementEXEC

程序只要重復(fù)執(zhí)行這段代碼, 直到 EXEC 的返回值不是nil-reply回復(fù)即可。

Redis 腳本和事務(wù)

從定義上來(lái)說(shuō), Redis 中的腳本本身就是一種事務(wù), 所以任何在事務(wù)里可以完成的事, 在腳本里面也能完成。 并且一般來(lái)說(shuō), 使用腳本要來(lái)得更簡(jiǎn)單,并且速度更快。

因?yàn)槟_本功能是 Redis 2.6 才引入的, 而事務(wù)功能則更早之前就存在了, 所以 Redis 才會(huì)同時(shí)存在兩種處理事務(wù)的方法。

不過(guò)我們并不打算在短時(shí)間內(nèi)就移除事務(wù)功能, 因?yàn)槭聞?wù)提供了一種即使不使用腳本, 也可以避免競(jìng)爭(zhēng)條件的方法, 而且事務(wù)本身的實(shí)現(xiàn)并不復(fù)雜。

不過(guò)在不遠(yuǎn)的將來(lái), 可能所有用戶都會(huì)只使用腳本來(lái)實(shí)現(xiàn)事務(wù)也說(shuō)不定。 如果真的發(fā)生這種情況的話, 那么我們將廢棄并最終移除事務(wù)功能。

redis事務(wù)的ACID特性

在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)中,嘗嘗用ACID特質(zhì)來(lái)檢測(cè)事務(wù)功能的可靠性和安全性。

在redis中事務(wù)總是具有原子性(Atomicity),一致性(Consistency)和隔離性(Isolation),并且當(dāng)redis運(yùn)行在某種特定的持久化
模式下,事務(wù)也具有耐久性(Durability).

①原子性

事務(wù)具有原子性指的是,數(shù)據(jù)庫(kù)將事務(wù)中的多個(gè)操作當(dāng)作一個(gè)整體來(lái)執(zhí)行,服務(wù)器要么就執(zhí)行事務(wù)中的所有操作,要么就一個(gè)操作也不執(zhí)行。

但是對(duì)于redis的事務(wù)功能來(lái)說(shuō),事務(wù)隊(duì)列中的命令要么就全部執(zhí)行,要么就一個(gè)都不執(zhí)行,因此redis的事務(wù)是具有原子性的。我們通常會(huì)知道

兩種關(guān)于redis事務(wù)原子性的說(shuō)法,一種是要么事務(wù)都執(zhí)行,要么都不執(zhí)行。另外一種說(shuō)法是redis事務(wù)當(dāng)事務(wù)中的命令執(zhí)行失敗后面的命令還
會(huì)執(zhí)行,錯(cuò)誤之前的命令不會(huì)回滾。其實(shí)這個(gè)兩個(gè)說(shuō)法都是正確的。但是缺一不可。我們接下來(lái)具體分析下

 我們先看一個(gè)可以正確執(zhí)行的事務(wù)例子
redis > MULTIOK redis > SET username "bugall"QUEUED redis > EXEC1) OK2) "bugall"
與之相反,我們?cè)賮?lái)看一個(gè)事務(wù)執(zhí)行失敗的例子。這個(gè)事務(wù)因?yàn)槊钤诜湃胧聞?wù)隊(duì)列的時(shí)候被服務(wù)器拒絕,所以事務(wù)中的所有命令都不會(huì)執(zhí)行,因?yàn)榍懊嫖覀冇薪榻B到,redis的事務(wù)命令是統(tǒng)一先放到事務(wù)隊(duì)列里,在用戶輸入EXEC命令的時(shí)候再統(tǒng)一執(zhí)行。但是我們錯(cuò)誤的使用"GET"命令,在命令放入事務(wù)隊(duì)列的時(shí)候被檢測(cè)到事務(wù),這時(shí)候還沒(méi)有接收到EXEC命令,所以這個(gè)時(shí)候不牽扯到回滾的問(wèn)題,在EXEC的時(shí)候發(fā)現(xiàn)事務(wù)隊(duì)列里有命令存在錯(cuò)誤,所以事務(wù)里的命令就全都不執(zhí)行,這樣就達(dá)到里事務(wù)的原子性,我們看下例子。
redis > MULTIOK redis > GET(error) ERR wrong number of arguments for 'get' command redis > GET usernameQUEUED redis > EXEC(error) EXECABORT Transaction discarded because of previous errors
redis的事務(wù)和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)事務(wù)的最大區(qū)別在于,redis不支持事務(wù)的回滾機(jī)制,即使事務(wù)隊(duì)列中的某個(gè)命令在執(zhí)行期間出現(xiàn)錯(cuò)誤,整個(gè)事務(wù)也會(huì)繼續(xù)執(zhí)行下去,直到將事務(wù)隊(duì)列中的所有命令都執(zhí)行完畢為止,我們看下面的例子
redis > SET username "bugall"OK redis > MULTIOK redis > SADD member "bugall" "litengfe" "yangyifang"QUEUED redis > RPUSH username "b" "l" "y" //錯(cuò)誤對(duì)鍵username使用列表鍵命令QUEUED redis > SADD password "123456" "123456" "123456"QUEUED redis > EXEC1) (integer) 32) (error) WRONGTYPE Operation against a key holding the wrong kind of value3) (integer) 3
redis的作者在十五功能的文檔中解釋說(shuō),不支持事務(wù)回滾是因?yàn)檫@種復(fù)雜的功能和redis追求的簡(jiǎn)單高效的設(shè)計(jì)主旨不符合,并且他認(rèn)為,redis事務(wù)的執(zhí)行時(shí)錯(cuò)誤通常都是編程錯(cuò)誤造成的,這種錯(cuò)誤通常只會(huì)出現(xiàn)在開(kāi)發(fā)環(huán)境中,而很少會(huì)在實(shí)際的生產(chǎn)環(huán)境中出現(xiàn),所以他認(rèn)為沒(méi)有必要為redis開(kāi)發(fā)事務(wù)回滾功能。所以我們?cè)谟懻搑edis事務(wù)回滾的時(shí)候,一定要區(qū)分命令發(fā)生錯(cuò)誤的時(shí)候。

②一致性

    事務(wù)具有一致性指的是,如果數(shù)據(jù)庫(kù)在執(zhí)行事務(wù)之前是一致的,那么在事務(wù)執(zhí)行之后,無(wú)論事務(wù)是否執(zhí)行成功,數(shù)據(jù)庫(kù)也應(yīng)該仍然一致的。    ”一致“指的是數(shù)據(jù)符合數(shù)據(jù)庫(kù)本身的定義和要求,沒(méi)有包含非法或者無(wú)效的錯(cuò)誤數(shù)據(jù)。redis通過(guò)謹(jǐn)慎的錯(cuò)誤檢測(cè)和簡(jiǎn)單的設(shè)計(jì)來(lái)保證事務(wù)一致性。

③隔離性

    事務(wù)的隔離性指的是,即使數(shù)據(jù)庫(kù)中有多個(gè)事務(wù)并發(fā)在執(zhí)行,各個(gè)事務(wù)之間也不會(huì)互相影響,并且在并發(fā)狀態(tài)下執(zhí)行的事務(wù)和串行執(zhí)行的事務(wù)產(chǎn)生的結(jié)果完全    相同。    因?yàn)閞edis使用單線程的方式來(lái)執(zhí)行事務(wù)(以及事務(wù)隊(duì)列中的命令),并且服務(wù)器保證,在執(zhí)行事務(wù)期間不會(huì)對(duì)事物進(jìn)行中斷,因此,redis的事務(wù)總是以串行    的方式運(yùn)行的,并且事務(wù)也總是具有隔離性的

④持久性

    事務(wù)的耐久性指的是,當(dāng)一個(gè)事務(wù)執(zhí)行完畢時(shí),執(zhí)行這個(gè)事務(wù)所得的結(jié)果已經(jīng)被保持到永久存儲(chǔ)介質(zhì)里面。    因?yàn)閞edis事務(wù)不過(guò)是簡(jiǎn)單的用隊(duì)列包裹起來(lái)一組redis命令,redis并沒(méi)有為事務(wù)提供任何額外的持久化功能,所以redis事務(wù)的耐久性由redis使用的模式    決定    - 當(dāng)服務(wù)器在無(wú)持久化的內(nèi)存模式下運(yùn)行時(shí),事務(wù)不具有耐久性,一旦服務(wù)器停機(jī),包括事務(wù)數(shù)據(jù)在內(nèi)的所有服務(wù)器數(shù)據(jù)都將丟失    - 當(dāng)服務(wù)器在RDB持久化模式下運(yùn)作的時(shí)候,服務(wù)器只會(huì)在特定的保存條件滿足的時(shí)候才會(huì)執(zhí)行BGSAVE命令,對(duì)數(shù)據(jù)庫(kù)進(jìn)行保存操作,并且異步執(zhí)行的BGSAVE不    能保證事務(wù)數(shù)據(jù)被第一時(shí)間保存到硬盤(pán)里面,因此RDB持久化模式下的事務(wù)也不具有耐久性    - 當(dāng)服務(wù)器運(yùn)行在AOF持久化模式下,并且appedfsync的選項(xiàng)的值為always時(shí),程序總會(huì)在執(zhí)行命令之后調(diào)用同步函數(shù),將命令數(shù)據(jù)真正的保存到硬盤(pán)里面,因此    這種配置下的事務(wù)是具有耐久性的。    - 當(dāng)服務(wù)器運(yùn)行在AOF持久化模式下,并且appedfsync的選項(xiàng)的值為everysec時(shí),程序會(huì)每秒同步一次
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容