redis-transaction
注意
-
不支持回滾操作
是因?yàn)閞edis是先執(zhí)行指令然后做日志话原,所以即使發(fā)生異常猎贴,沒有可以用來執(zhí)行回滾操作的日志。 - 只保證事物的
隔離性
, 不保證原子性
. -
redis
禁止在multi
和exec
之間執(zhí)行watch
指令,而必須在multi
之前做好盯住關(guān)鍵變量绪钥,否則會(huì)出錯(cuò)。
事物的過程
multi:
事物的開始(創(chuàng)建一個(gè)事物);
exec:
事物的執(zhí)行;
discard:
丟棄這個(gè)事物;
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 2
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> exec
1) (integer) 3
2) (integer) 4
3) (integer) 5
原理
redis 單線程且本身保證有序,且能保證不被其他指令打擾.--僅僅是保證了隔離性
redis multi和exec命令不能保證原子性,中間執(zhí)行的多個(gè)命令有一個(gè)失敗了,不會(huì)影響其他命令的執(zhí)行.
redis multi和exec僅僅保證一堆命令不被插隊(duì),順序執(zhí)行.原理是在server端開啟了一個(gè)事物隊(duì)列.
優(yōu)化
建議使用pipeline 提升性能.
pipe = redis.pipeline(transaction=true)
pipe.multi()
pipe.incr("books")
pipe.incr("books")
values = pipe.execute()
避免并發(fā)問題
悲觀鎖: 分布式鎖
樂觀鎖: watch機(jī)制
watch機(jī)制
> watch books
OK
> incr books # 被修改了
(integer) 1
> multi
OK
> incr books
QUEUED
> exec # 事務(wù)執(zhí)行失敗
(nil)
watch
會(huì)實(shí)時(shí)檢查觀察的key
是否被改變,如果改變了exec
提交會(huì)執(zhí)行失敗,返回null
.