日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > 互聯(lián)網(wǎng) > redis事物

redis事物

來源:程序員人生   發(fā)布時(shí)間:2014-11-14 08:43:59 閱讀次數(shù):4277次

本文檔翻譯自: http://redis.io/topics/transactions 。

MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事務(wù)的基礎(chǔ)。

事務(wù)可以1次履行多個(gè)命令, 并且?guī)в幸韵聝蓚€(gè)重要的保證:

  • 事務(wù)是1個(gè)單獨(dú)的隔離操作:事務(wù)中的所有命令都會(huì)序列化、按順序地履行。事務(wù)在履行的進(jìn)程中,不會(huì)被其他客戶端發(fā)送來的命令要求所打斷。

  • 事務(wù)是1個(gè)原子操作:事務(wù)中的命令要末全部被履行,要末全部都不履行。

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

    • 如果客戶端在使用 MULTI 開啟了1個(gè)事務(wù)以后,卻由于斷線而沒有成功履行 EXEC ,那末事務(wù)中的所有命令都不會(huì)被履行。
    • 另外一方面,如果客戶端成功在開啟事務(wù)以后履行 EXEC ,那末事務(wù)中的所有命令都會(huì)被履行。

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

    但是,如果 Redis http://www.jyygyx.com/server/由于某些緣由被管理員殺死,或遇上某種硬件故障,那末可能只有部份事務(wù)命令會(huì)被成功寫入到磁盤中。

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

    使用 redis-check-aof 程序可以修復(fù)這1問題:它會(huì)移除 AOF 文件中不完全事務(wù)的信息,確保http://www.jyygyx.com/server/可以順利啟動(dòng)。

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

用法

MULTI 命令用于開啟1個(gè)事務(wù),它總是返回 OK 。

MULTI 履行以后, 客戶端可以繼續(xù)向http://www.jyygyx.com/server/發(fā)送任意多條命令, 這些命令不會(huì)立即被履行, 而是被放到1個(gè)隊(duì)列中, 當(dāng) EXEC 命令被調(diào)用時(shí), 所有隊(duì)列中的命令才會(huì)被履行。

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

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

> MULTI
OK

> INCR foo
QUEUED

> INCR bar
QUEUED

> EXEC
1) (integer) 1
2) (integer) 1

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

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

事務(wù)中的毛病

使用事務(wù)時(shí)可能會(huì)遇上以下兩種毛病:

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

對(duì)產(chǎn)生在 EXEC 履行之前的毛病,客戶端之前的做法是檢查命令入隊(duì)所得的返回值:如果命令入隊(duì)時(shí)返回 QUEUED ,那末入隊(duì)成功;否則,就是入隊(duì)失敗。如果有命令在入隊(duì)時(shí)失敗,那末大部份客戶端都會(huì)停止并取消這個(gè)事務(wù)。

不過,從 Redis 2.6.5 開始,http://www.jyygyx.com/server/會(huì)對(duì)命令入隊(duì)失敗的情況進(jìn)行記錄,并在客戶端調(diào)用 EXEC 命令時(shí),謝絕履行并自動(dòng)放棄這個(gè)事務(wù)。

在 Redis 2.6.5 之前, Redis 只履行事務(wù)中那些入隊(duì)成功的命令,而疏忽那些入隊(duì)失敗的命令。 而新的處理方式則使得在流水線(pipeline)中包括事務(wù)變得簡單,由于發(fā)送事務(wù)和讀取事務(wù)的回復(fù)都只需要和http://www.jyygyx.com/server/進(jìn)行1次通訊。

至于那些在 EXEC 命令履行以后所產(chǎn)生的毛病, 并沒有對(duì)它們進(jìn)行特別處理: 即便事務(wù)中有某個(gè)/某些命令在履行時(shí)產(chǎn)生了毛病, 事務(wù)中的其他命令依然會(huì)繼續(xù)履行。

從協(xié)議的角度來看這個(gè)問題,會(huì)更容易理解1些。 以下例子中, LPOP 命令的履行將出錯(cuò), 雖然調(diào)用它的語法是正確的:

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

MULTI
+OK

SET a 3
abc

+QUEUED
LPOP a

+QUEUED
EXEC

*2
+OK
-ERR Operation against a key holding the wrong kind of value

EXEC 返回兩條批量回復(fù)(bulk reply): 第1條是 OK ,而第2條是 -ERR 。 至于怎樣用適合的方法來表示事務(wù)中的毛病, 則是由客戶端自己決定的。

最重要的是記住這樣1條, 即便事務(wù)中有某條/某些命令履行失敗了, 事務(wù)隊(duì)列中的其他命令依然會(huì)繼續(xù)履行 ―― Redis 不會(huì)停止履行事務(wù)中的命令。

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

MULTI
+OK

INCR a b c
-ERR wrong number of arguments for 'incr' command

由于調(diào)用 INCR 命令的參數(shù)格式不正確, 所以這個(gè) INCR 命令入隊(duì)失敗。

為何 Redis 不支持回滾(roll back)

如果你有使用關(guān)系式http://www.jyygyx.com/db/的經(jīng)驗(yàn), 那末 “Redis 在事務(wù)失敗時(shí)不進(jìn)行回滾,而是繼續(xù)履行余下的命令”這類做法可能會(huì)讓你覺得有點(diǎn)奇怪。

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

  • Redis 命令只會(huì)由于毛病的語法而失敗(并且這些問題不能在入隊(duì)時(shí)發(fā)現(xiàn)),或是命令用在了毛病類型的鍵上面:這也就是說,從實(shí)用性的角度來講,失敗的命令是由編程毛病釀成的,而這些毛病應(yīng)當(dāng)在開發(fā)的進(jìn)程中被發(fā)現(xiàn),而不應(yīng)當(dāng)出現(xiàn)在生產(chǎn)環(huán)境中。
  • 由于不需要對(duì)回滾進(jìn)行支持,所以 Redis 的內(nèi)部可以保持簡單且快速。

有種觀點(diǎn)認(rèn)為 Redis 處理事務(wù)的做法會(huì)產(chǎn)生 bug , 但是需要注意的是, 在通常情況下, 回滾其實(shí)不能解決編程毛病帶來的問題。 舉個(gè)例子, 如果你本來想通過 INCR 命令將鍵的值加上 1 , 卻不謹(jǐn)慎加上了 2 , 又或?qū)γ☆愋偷逆I履行了 INCR , 回滾是沒有辦法處理這些情況的。

鑒于沒有任何機(jī)制能避免http://www.jyygyx.com自己釀成的毛病, 并且這類毛病通常不會(huì)在生產(chǎn)環(huán)境中出現(xiàn), 所以 Redis 選擇了更簡單、更快速的無回滾方式來處理事務(wù)。

放棄事務(wù)

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

redis> SET foo 1
OK

redis> MULTI
OK

redis> INCR foo
QUEUED

redis> DISCARD
OK

redis> GET foo
"1"

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

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

被 WATCH 的鍵會(huì)被監(jiān)視,并會(huì)發(fā)覺這些鍵是不是被改動(dòng)過了。 如果有最少1個(gè)被監(jiān)視的鍵在 EXEC 履行之前被修改了, 那末全部事務(wù)都會(huì)被取消, EXEC 返回空多條批量回復(fù)(null multi-bulk reply)來表示事務(wù)已失敗。

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

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

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

上面的這個(gè)實(shí)現(xiàn)在只有1個(gè)客戶真?zhèn)€時(shí)候可以履行得很好。 但是, 當(dāng)多個(gè)客戶端同時(shí)對(duì)同1個(gè)鍵進(jìn)行這樣的操作時(shí), 就會(huì)產(chǎn)生競(jìng)爭條件。

舉個(gè)例子, 如果客戶端 A 和 B 都讀取了鍵原來的值, 比如 10 , 那末兩個(gè)客戶端都會(huì)將鍵的值設(shè)為 11 , 但正確的結(jié)果應(yīng)當(dāng)是 12才對(duì)。

有了 WATCH , 我們就能夠輕松地解決這類問題了:

WATCH mykey

val = GET mykey
val = val + 1

MULTI
SET mykey $val
EXEC

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

這類情勢(shì)的鎖被稱作樂觀鎖, 它是1種非常強(qiáng)大的鎖機(jī)制。 并且由于大多數(shù)情況下, 不同的客戶端會(huì)訪問不同的鍵, 碰撞的情況1般都很少, 所以通常其實(shí)不需要進(jìn)行重試。

了解 WATCH

WATCH 使得 EXEC 命令需要有條件地履行: 事務(wù)只能在所有被監(jiān)視鍵都沒有被修改的條件下履行, 如果這個(gè)條件不能滿足的話,事務(wù)就不會(huì)被履行。

如果你使用 WATCH 監(jiān)視了1個(gè)帶過期時(shí)間的鍵, 那末即便這個(gè)鍵過期了, 事務(wù)依然可以正常履行, 關(guān)于這方面的詳細(xì)情況,請(qǐng)看這個(gè)帖子: http://code.google.com/p/redis/issues/detail?id=270

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

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

redis> WATCH key1 key2 key3
OK

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

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

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

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

WATCH 可以用于創(chuàng)建 Redis 沒有內(nèi)置的原子操作。

舉個(gè)例子, 以下代碼實(shí)現(xiàn)了原創(chuàng)的 ZPOP 命令, 它可以原子地彈出有序集合中分值(score)最小的元素:

WATCH zset
element = ZRANGE zset 0 0
MULTI
    ZREM zset element
EXEC

程序只要重復(fù)履行這段代碼, 直到 EXEC 的返回值不是空多條回復(fù)(null multi-bulk reply)便可。

Redis 腳本和事務(wù)

從定義上來講, Redis 中的腳本本身就是1種事務(wù), 所以任何在事務(wù)里可以完成的事, 在腳本里面也能完成。 并且1般來講, 使用腳本要來得更簡單,并且速度更快。

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

不過我們其實(shí)不打算在短時(shí)間內(nèi)就移除事務(wù)功能, 由于事務(wù)提供了1種即便不使用腳本, 也能夠避免競(jìng)爭條件的方法, 而且事務(wù)本身的實(shí)現(xiàn)其實(shí)不復(fù)雜。

不過在不遠(yuǎn)的將來, 可能所有用戶都會(huì)只使用腳本來實(shí)現(xiàn)事務(wù)也說不定。 如果真的產(chǎn)生這類情況的話, 那末我們將廢棄并終究移除事務(wù)功能。

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 高清18麻豆 | 九九九久久国产免费 | 天天操夜夜曰 | 国产在线激情视频 | 国产专区在线播放 | 秋霞午夜影院 | 蜜乳av另类精品一区二区 | 国产欧美精品一区 | 欧美一级免费观看 | 九九热在线观看视频 | 免费看男女www网站入口在线 | 亚洲色图 欧美 | 国产精品久久久久久a | 久久久www成人免费精品张筱雨 | 亚洲成人av在线 | 亚洲成人自拍 | 亚洲福利 | 全部免费毛片在线播放网站 | 18性xxxxx性猛交 | 欧美日韩成人精品 | 希岛爱理和黑人中文字幕系列 | 日韩精品网 | 久久国产精品久久久久久久久久 | 日韩专区在线观看 | 日韩在线视频免费 | 精品国产一区二区三区免费 | 国产99久久久久久免费看农村 | 国内av免费 | 亚洲男人网站 | 福利视频1000| 成人毛片在线观看 | 亚洲国产欧美在线 | 亚洲视频精品一区 | 热久久免费视频 | 成人免费网站视频 | 成人片在线看 | 午夜激情福利视频 | 91超碰在线免费观看 | 91久久精品国产91久久 | 丰满少妇高潮惨叫久久久一 | 日韩欧美自拍偷拍 |