多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > redis事物

redis事物

來源:程序員人生   發布時間:2014-11-14 08:43:59 閱讀次數:4270次

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

MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事務的基礎。

事務可以1次履行多個命令, 并且帶有以下兩個重要的保證:

  • 事務是1個單獨的隔離操作:事務中的所有命令都會序列化、按順序地履行。事務在履行的進程中,不會被其他客戶端發送來的命令要求所打斷。

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

    EXEC 命令負責觸發并履行事務中的所有命令:

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

    當使用 AOF 方式做持久化的時候, Redis 會使用單個 write(2) 命令將事務寫入到磁盤中。

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

    如果 Redis 在重新啟動時發現 AOF 文件出了這樣的問題,那末它會退出,并匯報1個毛病。

    使用 redis-check-aof 程序可以修復這1問題:它會移除 AOF 文件中不完全事務的信息,確保http://www.vxbq.cn/server/可以順利啟動。

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

用法

MULTI 命令用于開啟1個事務,它總是返回 OK 。

MULTI 履行以后, 客戶端可以繼續向http://www.vxbq.cn/server/發送任意多條命令, 這些命令不會立即被履行, 而是被放到1個隊列中, 當 EXEC 命令被調用時, 所有隊列中的命令才會被履行。

另外一方面, 通過調用 DISCARD , 客戶端可以清空事務隊列, 并放棄履行事務。

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

> MULTI
OK

> INCR foo
QUEUED

> INCR bar
QUEUED

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

EXEC 命令的回復是1個數組, 數組中的每一個元素都是履行事務中的命令所產生的回復。 其中, 回復元素的前后順序和命令發送的前后順序1致。

當客戶端處于事務狀態時, 所有傳入的命令都會返回1個內容為 QUEUED 的狀態回復(status reply), 這些被入隊的命令將在 EXEC命令被調用時履行。

事務中的毛病

使用事務時可能會遇上以下兩種毛病:

  • 事務在履行 EXEC 之前,入隊的命令可能會出錯。比如說,命令可能會產生語法毛病(參數數量毛病,參數名毛病,等等),或其他更嚴重的毛病,比如內存不足(如果http://www.vxbq.cn/server/使用 maxmemory 設置了最大內存限制的話)。
  • 命令可能在 EXEC 調用以后失敗。舉個例子,事務中的命令可能處理了毛病類型的鍵,比如將列表命令用在了字符串鍵上面,諸如此類。

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

不過,從 Redis 2.6.5 開始,http://www.vxbq.cn/server/會對命令入隊失敗的情況進行記錄,并在客戶端調用 EXEC 命令時,謝絕履行并自動放棄這個事務。

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

至于那些在 EXEC 命令履行以后所產生的毛病, 并沒有對它們進行特別處理: 即便事務中有某個/某些命令在履行時產生了毛病, 事務中的其他命令依然會繼續履行。

從協議的角度來看這個問題,會更容易理解1些。 以下例子中, LPOP 命令的履行將出錯, 雖然調用它的語法是正確的:

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

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

以下例子展現的是另外一種情況, 當命令在入隊時產生毛病, 毛病會立即被返回給客戶端:

MULTI
+OK

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

由于調用 INCR 命令的參數格式不正確, 所以這個 INCR 命令入隊失敗。

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

如果你有使用關系式http://www.vxbq.cn/db/的經驗, 那末 “Redis 在事務失敗時不進行回滾,而是繼續履行余下的命令”這類做法可能會讓你覺得有點奇怪。

以下是這類做法的優點:

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

有種觀點認為 Redis 處理事務的做法會產生 bug , 但是需要注意的是, 在通常情況下, 回滾其實不能解決編程毛病帶來的問題。 舉個例子, 如果你本來想通過 INCR 命令將鍵的值加上 1 , 卻不謹慎加上了 2 , 又或對毛病類型的鍵履行了 INCR , 回滾是沒有辦法處理這些情況的。

鑒于沒有任何機制能避免http://www.vxbq.cn自己釀成的毛病, 并且這類毛病通常不會在生產環境中出現, 所以 Redis 選擇了更簡單、更快速的無回滾方式來處理事務。

放棄事務

當履行 DISCARD 命令時, 事務會被放棄, 事務隊列會被清空, 并且客戶端會從事務狀態中退出:

redis> SET foo 1
OK

redis> MULTI
OK

redis> INCR foo
QUEUED

redis> DISCARD
OK

redis> GET foo
"1"

使用 check-and-set 操作實現樂觀鎖

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

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

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

首先我們可能會這樣做:

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

上面的這個實現在只有1個客戶真個時候可以履行得很好。 但是, 當多個客戶端同時對同1個鍵進行這樣的操作時, 就會產生競爭條件。

舉個例子, 如果客戶端 A 和 B 都讀取了鍵原來的值, 比如 10 , 那末兩個客戶端都會將鍵的值設為 11 , 但正確的結果應當是 12才對。

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

WATCH mykey

val = GET mykey
val = val + 1

MULTI
SET mykey $val
EXEC

使用上面的代碼, 如果在 WATCH 履行以后, EXEC 履行之前, 有其他客戶端修改了 mykey 的值, 那末當前客戶真個事務就會失敗。 程序需要做的, 就是不斷重試這個操作, 直到沒有產生碰撞為止。

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

了解 WATCH

WATCH 使得 EXEC 命令需要有條件地履行: 事務只能在所有被監視鍵都沒有被修改的條件下履行, 如果這個條件不能滿足的話,事務就不會被履行。

如果你使用 WATCH 監視了1個帶過期時間的鍵, 那末即便這個鍵過期了, 事務依然可以正常履行, 關于這方面的詳細情況,請看這個帖子: http://code.google.com/p/redis/issues/detail?id=270

WATCH 命令可以被調用屢次。 對鍵的監視從 WATCH 履行以后開始生效, 直到調用 EXEC 為止。

用戶還可以在單個 WATCH 命令中監視任意多個鍵, 就像這樣:

redis> WATCH key1 key2 key3
OK

當 EXEC 被調用時, 不管事務是不是成功履行, 對所有鍵的監視都會被取消。

另外, 當客戶端斷開連接時, 該客戶端對鍵的監視也會被取消。

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

使用 WATCH 實現 ZPOP

WATCH 可以用于創建 Redis 沒有內置的原子操作。

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

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

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

Redis 腳本和事務

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

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

不過我們其實不打算在短時間內就移除事務功能, 由于事務提供了1種即便不使用腳本, 也能夠避免競爭條件的方法, 而且事務本身的實現其實不復雜。

不過在不遠的將來, 可能所有用戶都會只使用腳本來實現事務也說不定。 如果真的產生這類情況的話, 那末我們將廢棄并終究移除事務功能。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: jizzjizz免费 | 久久综合九色综合欧洲色 | 亚洲第一永久在线观看 | 香蕉伊 | 欧美性猛交xxxxbbb | 亚洲精品推荐 | 日本一区二区在线播放 | 免费中日高清无专码有限公司 | 色站综合 | 精品国产欧美一区二区最新 | 中文字幕最新在线 | jizzjizz免费大全| 亚洲小说区图片区另类春色 | 在线视频中文 | 国产精品亚洲欧美大片在线看 | 最近中文字幕mv免费看 | 色图片小说| 日韩理论片在线观看 | 成年人视频在线免费观看 | 亚拍精品一区二区三区 | 欧美色惰aⅴ | 久久精品免费全国观看国产 | 日韩 国产 在线 | 一区小说二区另类小说三区图 | 亚洲欧美日韩精品中文乱码 | 成人亚洲国产精品久久 | 在线观看中文字幕码2022 | 国产成人久久久精品毛片 | 精品久久免费观看 | 久久综合国产 | 久久亚洲日本不卡一区二区 | 成人免费性视频 | 久久精品免视看国产明星 | 欧美黑人猛烈ⅹxxx 欧美黑人喷潮水xxxx | 久久久国产这里有的是精品 | 成年人免费观看的视频 | 中文乱码视亚洲 | 一区二区三区视频免费 | 三级不卡视频 | 一级特黄aa大片欧美网站 | 欧美日韩一区二区三区视频在线观看 |