亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Redis-事務(wù)即簡單鎖應(yīng)用

原創(chuàng) 2016-11-09 14:03:27 510
摘要:Redis支持簡單的事務(wù), Redis允許一組命令在單一步驟中執(zhí)行, 事務(wù)有兩個(gè)屬性事務(wù)是一個(gè)單獨(dú)的隔離操作, 事務(wù)中所有的命令都會(huì)序列化, 按照順序執(zhí)行.Redis事務(wù)是原子性的, 即要么都執(zhí)行, 要么都不執(zhí)行一個(gè)事務(wù)從開始到執(zhí)行會(huì)經(jīng)歷三個(gè)階段開始事務(wù)命令入隊(duì)執(zhí)行事務(wù)redis 與 mysql 事務(wù)的對(duì)比:注: rollback 與 discard 的區(qū)別如果已經(jīng)成功執(zhí)行了2條語句, 第3條語句

Redis支持簡單的事務(wù), Redis允許一組命令在單一步驟中執(zhí)行, 事務(wù)有兩個(gè)屬性

  • 事務(wù)是一個(gè)單獨(dú)的隔離操作, 事務(wù)中所有的命令都會(huì)序列化, 按照順序執(zhí)行.

  • Redis事務(wù)是原子性的, 即要么都執(zhí)行, 要么都不執(zhí)行

一個(gè)事務(wù)從開始到執(zhí)行會(huì)經(jīng)歷三個(gè)階段

  • 開始事務(wù)

  • 命令入隊(duì)

  • 執(zhí)行事務(wù)

redis 與 mysql 事務(wù)的對(duì)比:

7.png

注: rollback 與 discard 的區(qū)別
如果已經(jīng)成功執(zhí)行了2條語句, 第3條語句出錯(cuò)
rollback后, 前兩條語句影響消失
discard只是結(jié)束本次事務(wù), 前兩條語句造成的影響依然存在
注:
在multi后面的語句中, 語句出錯(cuò)可能有2種情況

  • 語法本身有問題, 這種錯(cuò)誤exec時(shí)報(bào)錯(cuò), 所有語句得不到執(zhí)行

  • 語法本身沒錯(cuò)誤, 但適用對(duì)象有問題, 比如zadd操作list對(duì)象, exec后會(huì)執(zhí)行正確的語句, 并跳過有不適當(dāng)?shù)恼Z句

使用redis模擬銀行轉(zhuǎn)賬操作:

  • 正常情況

127.0.0.1:6379> set wang 200    #wang有200
OK
127.0.0.1:6379> set zhao 700    #zhao有700
OK
127.0.0.1:6379> 
127.0.0.1:6379> multi    #開啟事務(wù)
OK
127.0.0.1:6379> decrby zhao 100    #zhao減100
QUEUED
127.0.0.1:6379> incrby wang 100    #wang加100
QUEUED
#以上兩個(gè)QUEUED表示兩條語句被放在隊(duì)列里面, exec前并沒有執(zhí)行
127.0.0.1:6379> exec    #執(zhí)行完畢
1) (integer) 600
2) (integer) 300
127.0.0.1:6379>
  • 意外情況

127.0.0.1:6379> multi    開啟事務(wù)
OK
127.0.0.1:6379> 
127.0.0.1:6379> decrby zhao 100    #zhao減100
QUEUED
127.0.0.1:6379> das    #輸入一個(gè)錯(cuò)誤的命令
(error) ERR unknown command 'das'
127.0.0.1:6379> exec    #執(zhí)行, 提示被忽略
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> 
127.0.0.1:6379> mget zhao wang    #zhao 和 wang的值不變
1) "600"
2) "300"
127.0.0.1:6379>
  • 另一種報(bào)錯(cuò)情況

127.0.0.1:6379> multi
OK
127.0.0.1:6379> 
127.0.0.1:6379> decrby zhao 100    #zhao減100
QUEUED
127.0.0.1:6379> sadd wang pig    #故意把wang當(dāng)做數(shù)組加入一個(gè)key, 發(fā)現(xiàn)并沒有報(bào)錯(cuò), 
#因?yàn)檫@條語句被存放在隊(duì)列里, 并沒有被執(zhí)行
QUEUED
127.0.0.1:6379> exec    #此時(shí)語句才被執(zhí)行, 所以報(bào)錯(cuò), 但是zhao依然減了100, 說明執(zhí)行了正確的語句, 跳過了不正取的語句, 影響還在
1) (integer) 500
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> 
127.0.0.1:6379> mget zhao wang 
1) "500"
2) "300"
127.0.0.1:6379>
  • discard取消

127.0.0.1:6379> mget wang zhao
1) "400"
2) "400"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby zhao 100
QUEUED
127.0.0.1:6379> incrby wang 100
QUEUED
127.0.0.1:6379> 
127.0.0.1:6379> discard    #取消后值沒變
OK
127.0.0.1:6379> 
127.0.0.1:6379> mget wang zhao
1) "400"
2) "400"
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
127.0.0.1:6379>
127.0.0.1:6379> mget zhao wang
1) "400"
2) "400"
127.0.0.1:6379> 
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby zhao 100
QUEUED
127.0.0.1:6379> sadd wang pig
QUEUED
127.0.0.1:6379> 
127.0.0.1:6379> exec
1) (integer) 300
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> 
127.0.0.1:6379> discard    #不能discard
(error) ERR DISCARD without MULTI
127.0.0.1:6379> 
127.0.0.1:6379> mget zhao wang
1) "300"
2) "400"
127.0.0.1:6379>

watch key1 key2 ... keyN

作用: 監(jiān)聽 key1 key2 keyN有沒有變化, 如果有變化, 則事務(wù)取消

unwatch(不加key): 取消所有 watch 監(jiān)聽

場景: 一個(gè)人正在買票, ticket-1, money-100, 而票只有一張, 如果在我multi之后, exec之前票被別人買走, 即ticket變?yōu)?了, 怎么辦?

127.0.0.1:6379> set ticket 1    #加入只有1張票
OK
127.0.0.1:6379> set lisi 300    #lisi有300
OK
127.0.0.1:6379> set wang 300    #wang有300
OK
127.0.0.1:6379> 
127.0.0.1:6379> multi    #開啟事務(wù)
OK
127.0.0.1:6379> decr ticket    #票數(shù)-1
QUEUED
127.0.0.1:6379> decrby lisi 100    #lisi準(zhǔn)備買-100
QUEUED
127.0.0.1:6379> #此處還沒有exec

假如就在exec前票被別人買走, 打開另一個(gè)終端

127.0.0.1:6379> decr ticket    #票-1
(integer) 0
127.0.0.1:6379> get ticket    #此時(shí)票數(shù)為0
"0"
127.0.0.1:6379>

此時(shí)提交lisi

127.0.0.1:6379> exec
1) (integer) -1    #票變?yōu)?1
2) (integer) 200    #錢-100
127.0.0.1:6379>

因此上面的過程不合理

要解決上面的情況,要采用監(jiān)視

127.0.0.1:6379> set ticket 1    #票數(shù)為1
OK
127.0.0.1:6379> set lisi 200    #lisi錢是100
OK
127.0.0.1:6379> set wang 300    #wang是300
OK
127.0.0.1:6379> 
127.0.0.1:6379> watch ticket    #監(jiān)控ticket有沒有變動(dòng), 有變動(dòng)的話則事務(wù)取消
OK
127.0.0.1:6379> multi    #開啟事務(wù)
OK
127.0.0.1:6379> decr ticket    #ticket-1
QUEUED
127.0.0.1:6379> decrby lisi 100    #錢-100
QUEUED
127.0.0.1:6379>

在exec前票又被另一個(gè)人買走了

127.0.0.1:6379> decr ticket
(integer) 0
127.0.0.1:6379> get ticket
"0"
127.0.0.1:6379>

此時(shí)票數(shù)為0, lisi提交

127.0.0.1:6379> 
127.0.0.1:6379> exec    #失敗
(nil)
127.0.0.1:6379> 
127.0.0.1:6379> get lisi    #錢并沒有減少
"200"
127.0.0.1:6379>


發(fā)佈手記

熱門詞條