簡介
可以一次執行多個命令,本質是一組命令的集合.
一個事務中的所有命令都會序列化,按順序的串行化執行而不會被其他命令插入,不許加塞
作用
在一個佇列中,一次性,順序性,排他性的執行一系列命令
開啟事務示例
remoteSelf:1>multi
"OK"
remoteSelf:1>set k1 v1
"QUEUED"
remoteSelf:1>set k2 v2
"QUEUED"
remoteSelf:1>get k1
"QUEUED"
remoteSelf:1>exec
1) "OK"
2) "OK"
3) "v1"
放棄事務
remoteSelf:1>mget k1 k2
1) "v1"
2) "v2"
remoteSelf:1>multi
"OK"
remoteSelf:1>set k1 11
"QUEUED"
remoteSelf:1>set k2 22
"QUEUED"
remoteSelf:1>discard
"OK"
remoteSelf:1>mget k1 k2
1) "v1"
2) "v2"
一個失敗所有的都失敗(如果打完命令就報錯,此時全部回滾)
remoteSelf:1>keys *
1) "k2"
2) "k1"
3) "website"
4) "zset01"
remoteSelf:1>multi
"OK"
remoteSelf:1>set k3 v3
"QUEUED"
remoteSelf:1>set k4 v4
"QUEUED"
remoteSelf:1>getset k4
"ERR wrong number of arguments for 'getset' command"
remoteSelf:1>exec
"EXECABORT Transaction discarded because of previous errors."
remoteSelf:1>keys *
1) "k2"
2) "k1"
3) "website"
4) "zset01"
一個失敗其他的成功(如果打完命令沒有報錯,進入佇列,運行時報錯,則其他的運行成功,報錯的失敗)
remoteSelf:1>keys *
1) "k2"
2) "k1"
3) "website"
4) "zset01"
remoteSelf:1>mget k1 k2
1) "v1"
2) "v2"
remoteSelf:1>multi
"OK"
remoteSelf:1>incr k1
"QUEUED"
remoteSelf:1>set k3 v3
"QUEUED"
remoteSelf:1>exec
1) "ERR value is not an integer or out of range"
2) "OK"
remoteSelf:1>keys *
1) "website"
2) "zset01"
3) "k1"
4) "k2"
5) "k3"
watch監控.如果監控的資料發生了改變,則事務失效
悲觀鎖
pessimistic lock,每次拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,
這樣別人想拿這個資料就會block直到拿到鎖.
傳統的關系型資料庫里邊就用到了很多這種鎖機制,比如行所,表鎖等,讀鎖,寫鎖等,都是在操作之前先上鎖
樂觀鎖
optimistic lock,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,
可以使用版本號等機制.樂觀鎖適用于多讀的應用型別,這樣可以提高吞吐量.
樂觀鎖策略: 提交版本必須大于記錄當前版本才能執行更新
示例
127.0.0.1:8686[1]> mget balance debt
1) "100"
2) "0"
127.0.0.1:8686[1]> watch balance
OK
# watch之后執行更改balance
remoteSelf:1>set balance "200"
"OK"
remoteSelf:1>get balance
"200"
127.0.0.1:8686[1]> multi
OK
127.0.0.1:8686[1]> decrby balance 20
QUEUED
127.0.0.1:8686[1]> incrby debt 20
QUEUED
# 執行失敗
127.0.0.1:8686[1]> exec
(nil)
watch
watch指令,類似樂觀鎖,事務提交時,如果key的值已經被別的客戶端改變,整個事務佇列都不會被執行.
通過watch命令在事務執行之前監控了多個keys,倘若在watch之后有任何key的值發生了變化,
exec命令執行的事務都被放棄,同時回傳Nullmulti-bulk應答已通知呼叫者事務執行失敗
exec執行之后會取消對所有key的監控
127.0.0.1:8686[1]> get test
"10"
127.0.0.1:8686[1]> mget balance debt
1) "200"
2) "0"
127.0.0.1:8686[1]> watch balance test
OK
127.0.0.1:8686[1]> multi
OK
# 另外一個客戶端改變balance的值
remoteSelf:1>set balance "100"
"OK"
remoteSelf:1>get balance
"100"
127.0.0.1:8686[1]> incr balance
QUEUED
127.0.0.1:8686[1]> decr debt
QUEUED
# 執行事務失敗
127.0.0.1:8686[1]> exec
(nil)
127.0.0.1:8686[1]> mget balance debt
1) "100"
2) "0"
127.0.0.1:8686[1]> get test
"10"
# 之前已經監控了test不在監控
# 修改test的值
remoteSelf:1>set test "20"
"OK"
remoteSelf:1>get test
"20"
127.0.0.1:8686[1]> multi
OK
127.0.0.1:8686[1]> incr test
QUEUED
# 事務執行成功.證明了exec在執行時,會取消對所有key的監控
127.0.0.1:8686[1]> exec
1) (integer) 21
unwatch會取消所有key的監控
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/19759.html
標籤:NoSQL
上一篇:redis組態檔詳解
下一篇:redis的發布訂閱
