Chapter4 Redis事务
4.1 Redis 的事务
4.1.1 事务简介
- Redis 的事务允许在一次单独的步骤中执行一组命令,并且能够保证将一个事务中的所有命令序列化,然后按顺序执行;
- 在一个 Redis 事务中, Redis 要么执行其中的所有命令,要么什么都不执行,即 Redis 的事务要能够保证序列化和原子性。
4.1.2 事务的错误处理
- 组队中某个命令出现报告错误:整个队列被取消
- 执行阶段某个命令报错:该命令不执行,其它命令会被执行,不回滚
4.2 Redis 事务的常用命令
4.2.1 multi
用于标记事务块的开始。 Redis 会将后续的命令逐个放入队列中,然后才能使用 EXEC 命令原子化地执行这个命令序列
示例
开启事务
127.0.0.1:6379> multi OK
添加
127.0.0.1:6379> set s1 v1q QUEUED 127.0.0.1:6379> get s1 QUEUED
4.2.2 exec
在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态
返回一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值
示例
127.0.0.1:6379> multi OK 127.0.0.1:6379> set s1 vps QUEUED 127.0.0.1:6379> get s1 QUEUED 127.0.0.1:6379> exec 1) OK 2) "vps"
4.2.3 discard
清除所有先前在一个事务中放入队列的命令,并且结束事务
如果使用了 WATCH 命令,那么 DISCARD 命令就会将当前连接监控的所有键取消监控
示例
127.0.0.1:6379> multi OK 127.0.0.1:6379> set s1 watch QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> exec (error) ERR EXEC without MULTI
4.2.4 watch
语法
watch key [key...]
监控键值:
- 如果被监控的 key 值在本事务外有修改时,则本事务所有指令都不会被执行
- Watch 命令相当于关系型数据库中的乐观锁
示例
127.0.0.1:6379> watch s1 OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> set s1 watch QUEUED 127.0.0.1:6379> strlen s1 QUEUED 127.0.0.1:6379> get s1 QUEUED # 启动另一个客户端,修改s1 # 127.0.0.1:6379> set s1 s111 # OK 127.0.0.1:6379> exec (nil)
4.2.5 unwatch
- 清除所有先前为一个事务监控的键
- 如果在 watch 命令之后调用了 EXEC 或 DISCARD 命令,那么就不需要手动调用 UNWATCH 命令
4.3 Redis 三特性
4.3.1 单独的隔离操作
- 事务中的所有命令都会序列化、顺序地执行
- 事务在执行过程中, 不会被其它客户端发来的命令请求所打断,除非使用 watch 命令监控某些键
4.3.2 没有隔离级别的概念
- 队列的命令提交前不会被执行
- 因为未执行任何命令,自然也不存在脏读等问题
4.3.3 不保证事务的原子性
- redis 同一个事务中如果一条命令执行失败,其后的命令仍然可能会被执行, redis 的事务没有回滚
- Redis 已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为 Redis 不需要事务回滚的能力