Redis事务管理
一、什么是事務
事務是數(shù)據(jù)庫管理系統(tǒng)執(zhí)行過程中的一個邏輯單位,由一個有限的數(shù)據(jù)庫操作序列構(gòu)成。
二、Redis 事務常用命令
三、Case 案例
為了說明情況在相對應的命令后面加了解釋。
3.1 正確執(zhí)行
127.0.0.1:6379> MULTI // 開啟事務 OK 127.0.0.1:6379> set k1 v1 QUEUED // QUEUED 表示入隊 127.0.0.1:6379> get k1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> EXEC // 執(zhí)行事務 1) OK 2) "v1" 3) OK3.2 取消事務
127.0.0.1:6379> FLUSHDB // 清空數(shù)據(jù) OK 127.0.0.1:6379> MULTI // 開啟事務 OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> DISCARD // 取消事務 OK 127.0.0.1:6379> get k1 (nil)3.3 語法出錯,事務回滾
127.0.0.1:6379> FLUSHDB // 清空數(shù)據(jù) OK 127.0.0.1:6379> MULTI // 開啟事務 OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 // 模擬出錯 (error) ERR wrong number of arguments for 'set' command 127.0.0.1:6379> EXEC // 執(zhí)行事務 (error) EXECABORT Transaction discarded because of previous errors. // 事務因為前面的錯誤被取消 127.0.0.1:6379> get k1 (nil) 127.0.0.1:6379> keys * (empty list or set)注:如果執(zhí)行的命令本身語法出錯 (在事務中出錯),那么這個事務中的所有命令都不會執(zhí)行。
3.4 非語法錯誤,事務不回滾
127.0.0.1:6379> FLUSHDB // 清空數(shù)據(jù) OK 127.0.0.1:6379> MULTI // 開啟事務 OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> INCR k1 // 使 k1 自增 1 QUEUED 127.0.0.1:6379> EXEC // 執(zhí)行事務 1) OK 2) OK // 前兩條命令正確執(zhí)行 3) (error) ERR value is not an integer or out of range // 由于 v1 是 String 類型不能自增,第三條命令報錯 127.0.0.1:6379> mget k1 k2 1) "v1" 2) "v2"注:如果在事務執(zhí)行時出錯 (在事務中不出錯),那么只有出錯的命令不執(zhí)行,其他正確的命令會被執(zhí)行。
Redis 與傳統(tǒng)的關(guān)系型數(shù)據(jù)庫事務最大的區(qū)別在于,Redis 不支持事務回滾機制。
Redis 的作者在事務功能文檔中解釋道:不支持復雜的事務回滾機制是因為與 Redis 追求的簡單高效主旨不符,并且他認為事務執(zhí)行出錯往往都是編程錯誤導致的,所以他認為沒有必要為 Redis 設計事務回滾功能。
3.5 WATCH 監(jiān)控 key
正確執(zhí)行:
127.0.0.1:6379> FLUSHDB // 清空數(shù)據(jù) OK 127.0.0.1:6379> set money 100 // 初始化 money 為 100 OK 127.0.0.1:6379> WATCH money // 監(jiān)視 money OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> DECRBY money 10 // 將 money 減少 10 QUEUED 127.0.0.1:6379> EXEC // 執(zhí)行事務,money 變?yōu)?90 1) (integer) 90 127.0.0.1:6379> get money "90"出錯:
127.0.0.1:6379> WATCH money // 監(jiān)視 money ,此時 money 為 90 OK 127.0.0.1:6379> DECRBY money 10 // 在事務開始之前將 money 減少 10,money 為 80 (integer) 80 127.0.0.1:6379> get money "80" 127.0.0.1:6379> MULTI // 開啟事務 OK 127.0.0.1:6379> DECRBY money 10 // 在事務中將 money 減少 10 QUEUED 127.0.0.1:6379> EXEC // 執(zhí)行事務,沒有命令被執(zhí)行 (nil) 127.0.0.1:6379> get money // 查看 money 仍然為 80 "80"注:在對一個 (或幾個) key 進行監(jiān)視之后,如果這個 (或者幾個) key 的值在事務開啟之前發(fā)生變化,那么在事務中操作這個 (幾個)key 的命令將會被打斷,有點類似樂觀鎖的作用。
3.6 UNWATCH 取消監(jiān)視所有 key
127.0.0.1:6379> WATCH money // 監(jiān)視 money 當前 money 為 80 OK 127.0.0.1:6379> UNWATCH // 取消對所有 key 的監(jiān)視 OK 127.0.0.1:6379> DECRBY money 10 // 在事務執(zhí)行之前將 money 減少 10 ,當前執(zhí)行完 money 為 70 (integer) 70 127.0.0.1:6379> get money "70" 127.0.0.1:6379> MULTI // 開啟事務 OK 127.0.0.1:6379> DECRBY money 10 // 將 money 減少 10 QUEUED 127.0.0.1:6379> EXEC // 執(zhí)行事務,命令被正確執(zhí)行 1) (integer) 60 127.0.0.1:6379> get money // money 被改為了 60 "60"注:在對 key 進行監(jiān)視之后,如果想要在事務開啟之前操作被監(jiān)視的 key ,那么可以通過 UNWATCH 取消對所有 key 的監(jiān)控。
四、總結(jié)
4.1 事務的三個狀態(tài)
- 開始:以 MULTI 開始一個事務
- 入隊:將多個命令入隊到事務中,接到這些命令并不會立即執(zhí)行,而是放到等待執(zhí)行的事務隊列里面
- 執(zhí)行:由 EXEC 命令觸發(fā)事務
4.2 事務特性
- 原子性:Redis 具備原子性,但是命令執(zhí)行出錯后不支持事務回滾
- 一致性:Redis 具備一致性
- 隔離性:Redis 采用單線程執(zhí)行,因此事務總是以串行的方式執(zhí)行,因此 Redis 也是具備隔離性的
- 持久性:Redis 的持久性意味著執(zhí)行事務產(chǎn)生的結(jié)果被永久性的保存到硬盤里,即使服務器宕機,數(shù)據(jù)也不應該丟失,因此 Redis 的持久性由 Redis 的持久化方案決定。當服務器在 AOF 持久化模型下,當 appendfync 配置為 always 時,Redis 的事務也具備持久性
總結(jié)
- 上一篇: 1950年解放军副师长遇难电影叫什么
- 下一篇: MyBatis 获取数据库中自增主键值