redis對事務的支持目前還比較簡單。redis只能保證一個client發起的事務中的命令能夠連續的執行,而中間不會插入其餘client的命令。 因爲redis是單線程來處理全部client的請求的因此作到這點是很容易的。通常狀況下redis在接受到一個client發來的命令後會當即處理並 返回處理結果,可是當一個client在一個鏈接中發出multi命令有,這個鏈接會進入一個事務上下文,該鏈接後續的命令並非當即執行,而是先放到一 個隊列中。當今後鏈接受到exec命令後,redis會順序的執行隊列中的全部命令。並將全部命令的運行結果打包到一塊兒返回給client,而後結束事務上下文。redis
數據ACID特性知足了幾條?服務器
爲了保持簡單,redis事務保證了其中的一致性和隔離性;async
不知足原子性和持久性;spa
redis事務在執行的中途遇到錯誤,不會回滾全部的命令,而是繼續執行後續命令;(違反原子性)線程
事務能夠理解爲一個打包的批量執行腳本,但批量指令並不是原子化的操做;隊列
中間某條指令的失敗不會致使前面已作指令的回滾,也不會形成後續的指令不作;進程
示例:事務
127.0.0.1:6379> set b 11 # 設置 b 對應的 value 爲字符串類型內存
OK字符串
127.0.0.1:6379> multi # 開啓事物
OK
127.0.0.1:6379> sadd a aa aaa # 添加一個 set key 爲 a
QUEUED
127.0.0.1:6379> sadd b bb bbb # 添加一個 set key 爲 b,此時由於 b 對應的 key 已被佔用,並且對應的數據類型爲 string,因此這裏會失敗
QUEUED
127.0.0.1:6379> sadd c cc ccc # 添加一個 set key 爲 c
QUEUED
127.0.0.1:6379> exec # 提交事務,兩個成功一個失敗,並無所有回滾
1) (integer) 2
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) (integer) 2
127.0.0.1:6379> SMEMBERS a
1) "aa"
2) "aaa"
事務不過是用隊列包裹起了一組 Redis 命令,並無提供任何額外的持久性功能,因此事務的持久性由 Redis 所使用的持久化模式決定:
在單純的內存模式下,事務確定是不持久的。
在 RDB 模式下,服務器可能在事務執行以後、RDB 文件更新以前的這段時間失敗,因此 RDB 模式下的 Redis 事務也是不持久的。
在 AOF 的「老是 SYNC 」模式下,事務的每條命令在執行成功以後,都會當即調用 fsync 或 fdatasync 將事務數據寫入到 AOF 文件。可是,這種保存是由後臺線程進行的,主線程不會阻塞直到保存成功,因此從命令執行成功到數據保存到硬盤之間,仍是有一段很是小的間隔,因此這種模式下的事務也是不持久的。
其餘 AOF 模式也和「老是 SYNC 」模式相似,因此它們都是不持久的。
redis事務在執行的過程當中,不會處理其它命令,而是等全部命令都執行完後,再處理其它命令(知足隔離性)
redis事務在執行過程當中發生錯誤或進程被終結,都能保證數據的一致性;
事務回滾
另外一個 client 修改 watchkey 的值,致使主窗口的事務提交失敗