一.是什么?
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行执行,而不会被其他命令加塞。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
二.Redis事务命令
命令 | 解释 |
---|---|
DISCARD | 取消事务,放弃执行事务块内的所有命令。 |
EXEC | 执行所有事务块内的命令。 |
MULTI | 标记一个事务块的开始。 |
UNWATCH | 取消 WATCH 命令对所有 key 的监视。 |
WATCH key [key …] | 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
三.例子
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED
redis 127.0.0.1:6379> GET book-name
QUEUED
redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
redis 127.0.0.1:6379> SMEMBERS tag
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"
四.两种出错状态
第一种称为全体连坐,可以看出整个事务都没有执行成功
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> setget k4 v4
(error) ERR unknown command `setget`, with args beginning with: `k4`, `v4`,
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 k1
(nil)
第二种称为罪魁祸首,可以看出在执行的过程,只有错误的那一句执行失败
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECR k1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> EXEC
1) (integer) -1
2) OK
3) OK
上面两种情况就好像在编写代码是一个是出现非常严重的语法错误直接gg,另一个就像1/0只有在编译时才报错。
五.Watch监控
首先知道几个概念:
悲观锁,表锁
乐观锁,行锁
redis采用的是乐观锁,在每一个记录的后面都有一个版本号,当有人修改记录后,版本后自动加1,跟svn非常相似。
但是如果两个人撞车了,比如说A在修改完准备提交时(版本号1->2),这时B提前提交一步(版本号1->2),这时A在提交时实际版本号为2,但是在A的记录中是1,这就造成了冲突,导致A不能提交。
所以这个时候就需要OnWatch监控它们,防止自己在改时被其他人加塞。