Redis 的事务

摘要:Redis 的事务,redis 是不完全支持事务的,redis 事务操作命令有 multi,discard,exec,watch,unwatch 等。

Redis 的事务

redis 的事务,其实和事务的理念就是一条命令,或者一组命令要么同时成功,要么同时失败。一个事务中的所有命令都会被串行化,按顺序的串行化执行而不会被其它命令插入,不许加塞。

一个队列中,一次性,顺序性,排他性的执行一系列命令。


Redis 事务的常用命令

MULTI 标记一个事务块的开始。
EXEC 执行所有事务块内的命令。
DISCARD 取消事务,放弃执行事务块内的所有命令。

WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
UNWATCH 取消 WATCH 命令对所有 key 的监视。


正常执行事务流程

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 k1
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) "v1"


放弃提交事务

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v11
QUEUED
127.0.0.1:6379> set k2 v22
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> get k1
"v1"


Redis 没有事务隔离级别的概念

队列中的命令,没有提交之前都不会被实际的执行,因为事务没有被实际的执行,也就不存在,我自己在事务内的更新,我再次查看会查看到。


Redis 不完全支持事务

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> dfsffd k1
(error) ERR unknown command `dfsffd`, with args beginning with: `k1`, 
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1
(nil)

一组命令执行过程中,如果发现报错,比如我们输入一个不存在的命令,在执行中报错,最后 exec 提交事务,所有的命令都不会成功。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 aa
QUEUED
127.0.0.1:6379> INCR k1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
127.0.0.1:6379> MGET k1 k2
1) "aa"
2) "v2"

一组命令执行过程中,如果执行命令没有发生报错,比如我们在事务中给一个 key 为 aa 的值,执行 incr 自增 1 的命令时,会返回 queued 提示,表面上看着是正常的,但是 incr 无法给字符串 aa 自增 1,但是最后 exec 提交后,正常的命令会执行成功,错误的使用命令,就会报错。

所以说 redis 对事务的支持是部分支持的,不能保证事务的原子性,不是像 mysql 那样完全支持的。


WATCH 和 UNWATCH 命令

watch 相当于一个乐观锁,如果检测到你要提交的事务,被其他事务改动过,就提交失败,只有你的事务提交中的 key 没有被其他事务改过,才会提交成功。

利用 watch 监控一个或者多个 key,假如你开启 watch 后,有任何的 key 发生了变化, exec 提交命令执行的所有的事务都将被放弃。避免你在操作过程中有其他会话客户端修改你要改的 key,保证两个会话修改同一个 key 的变动发生在一个同一个事物中。

我们也可以在利用 unwatch 命令来取消检测。

结束语:感谢您对本网站文章的浏览,欢迎您的分享和转载,但转载请说明文章出处。
Top