資料acid特性滿足了幾條?
為了保持簡單,redis事務保證了其中的一致性和隔離性;
不滿足原子性和永續性;
redis事務在執行的中途遇到錯誤,不會回滾,而是繼續執行後續命令;(違反原子性)
事務可以理解為乙個打包的批量執行指令碼,但批量指令並非原子化的操作;
中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做;
比如:
redis
127.0
.0.1
:7000
>
multi
okredis
127.0
.0.1
:7000
>
seta aaa
queued
redis
127.0
.0.1
:7000
>
setb bbb
queued
redis
127.0
.0.1
:7000
>
setc ccc
queued
redis
127.0
.0.1
:7000
>
exec1)
ok2)ok
3)ok
如果在set b bbb處失敗,set a已成功不會回滾,set c還會繼續執行;
事務不過是用佇列包裹起了一組 redis 命令,並沒有提供任何額外的永續性功能,所以事務的永續性由 redis 所使用的持久化模式決定:
redis事務在執行的過程中,不會處理其它命令,而是等所有命令都執行完後,再處理其它命令(滿足隔離性)
redis事務在執行過程中發生錯誤或程序被終結,都能保證資料的一致性;(詳見參考資料1)
除了不保證原子性和永續性,在實際使用中還有以下問題:
1) 遇到有查詢的情況穿插在事務中間,不會返回結果;
設定事務開始標誌後,所有的命令都是queued,即使是查詢指令;
如果後續的更新操作需要依賴於前面的查詢指令,那redis事務就無法有效的完成任務;
例如:
redis
127.0
.0.1
:7000
>
multi
okredis
127.0
.0.1
:7000
>
seta aaa
queued
redis
127.0
.0.1
:7000
>
getb
queued
業務邏輯...
redis
127.0
.0.1
:7000
>
setc ccc
queued
redis
127.0
.0.1
:7000
>
exec1)
ok2)bbb3)
ok
第二步 get a 返回的是queued,並不是a的查詢結果,
如果後續的set操作依賴於get的結果(存在依賴業務邏輯),就不能將get操作放在事務操作中;
2) 事務中的每條命令都與redis伺服器進行了一次網路互動;
redis 事務指定開始後,執行乙個事務返回的都是queued,那這個入隊操作是在客戶端實現,還是在伺服器端實現的?
檢視原始碼,很容易發現是在伺服器端實現;
在redis.c中有這麼一段:
int
processcommand
(redisclient *c
)else
return
redis_ok
;}
這裡就涉及到客戶端與伺服器端的多次互動,明明是需要一次批量執行的n條命令,還需要通過多次網路互動,有些浪費;
如果有這樣的需求:在事務開始後,中間穿插有查詢邏輯;
那麼使用redis事務(單庫),無法滿足這個要求;
可能的解決方案:
可以考慮使用多個庫,讀寫分離,查詢庫只用來查詢,更新庫用來開事務做寫操作;
不再使用redis的事務指令,自己在客戶端將待執行的命令批量打包,決定是否回滾還是全部執行;這樣可以在更新的間隙執行查詢邏輯;而不需要將查詢邏輯提前到事務指令multi之前;
將查詢業務邏輯提前;嚴格規範**編寫要求,所有的redis查詢邏輯都放在事務之外:
redis
127.0
.0.1
:7000
>
getb
bbb業務邏輯...
redis
127.0
.0.1
:7000
>
multi
ok redis
127.0
.0.1
:7000
>
seta aaa
queued
redis
127.0
.0.1
:7000
>
setc ccc
queued
redis
127.0
.0.1
:7000
>
exec1)
ok 2)
ok
將多個命令打包批量傳送到redis伺服器執行,減少網路互動,優化效能,可能的解決方案:
對於所有的get/set操作,可使用現有的mget/mset指令;
對於各種不同型別的更新操作,可使用lua指令碼將命令打包後,傳送到伺服器端一次執行;
redis事務處理
1 multi命令用於開啟乙個事務,它總是返回ok multi執行之後,客戶端可以繼續向伺服器傳送任意多條命令,這些命令不會立即被執行,而是被放到乙個佇列中 2 exec命令被呼叫時,所有佇列中的命令才會被執行 multi ok incr foo queued set t1 1 queued exe...
Redis 事務處理
眾所周知,事務是指 乙個完整的動作,要麼全部執行,要麼什麼也沒有做 在聊 redis 事務處理之前,要先和大家介紹四個redis指令,即multi exec discard watch。這四個指令構成了redis事務處理的基礎。呼叫 exec 之前的錯誤 語法錯誤 呼叫exec之前的錯誤 有可能是由...
Redis的事務處理
multi 開啟事務 exec 提交事務 discard取消事務 127.0 0.1 6379 multi ok127.0 0.1 6379 set djkfdjs queued 127.0 0.1 6379 set djklg djgl queued 127.0 0.1 6379 discard ...