Redis事务本质:一组命令的集合;一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行。
Redis事务没有隔离级别的概念。
一次性、顺序性、排他性
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务。
- 命令入队。
- 执行事务exec。
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 > get k2 QUEUED 127.0.0.1:6379 > set k3 v3 QUEUED 127.0.0.1:6379 > exec #执行事务 1)OK 2)OK 3)"v2" 4)OK
放弃事务DISCARD
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 k4 v4 QUEUED 127.0.0.1:6379 > DISCARD #取消事务 OK 127.0.0.1:6379 > get k4 (nil)
编译型异常,事务中所有的命令都不会执行
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 v3 QUEUED 127.0.0.1:6379> getset k3 #错误的命令 (error)ERR wrong number of arguments for 'getset' command 127.0.0.1:6379> set k4 y4 QUEUED 127.0.0.1:6379> set k5 v5 QUEUED 127.0.0.1:6379>exec #执行事务 (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get k5 #所有的命令都不会被执行 (ni1)
运行时异常(1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常!
127.0.0.1:6379 > set kl "vl" OK 127.0.0.1:6379 > mu1ti OK 127.0.0.1:6379 > incr k1 #会执行的时候失败 QUEUED 127.0.0.1:6379 > set k2v2 QUEUED 127.0.0.1:6379 > set k3v3 QUEUED 127.0.0.1:6379 > get k3 QUEUED 127.0.0.1:6379 > exec 1)(error)ERR value is not an integer or out of range #虽然第一条命令报错了,但是依旧正常执行成功了 2) OK 3) OK 4) "v3" 127.0.0.1:6379 > get k2 "v2" 127.0.0.1:6379 > get k3 "v3"
监视
127.0.0.1:6379 > set money 100 OK 127.0.0.1:6379 > set out 0 OK 127.0.0.1:6379 > watch money #监视对象 OK 127.0.0.1:6379 > mu1ti OK 127.0.0.1:6379 > DECRBY money 20 QUEUED 127.0.0.1:6379 > INCRBY out 20 QUEUED 127.0.0.1:6379 > exec 1)(integer) 80 2)(integer) 20
事务的相关命令:
| 序号 | 命令及描述 |
|---|---|
| 1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
| 2 | EXEC 执行所有事务块内的命令。 |
| 3 | MULTI 标记一个事务块的开始。 |
| 4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
| 5 | WATCH key [key …] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |



