redis的事物

时间:2022-07-24
本文章向大家介绍redis的事物,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

涉及到的相关命令

  • multi
  • exec
  • discard
  • watch
  • unwatch

1:multi,exec

对于一般的关系型数据库的事物来说,事物的执行过程无非为 生成事物 产生命令 执行事物。对于redis来说,multi就是生成事物,exec就是执行事物,discard就是取消事物

基本执行过程如下图

redis的事物过程

可以看到,在我们执行set的时候命令并没有执行,而是写入到了一个控制事物的队列中,返回的信息是QUEUED,在最后exec的时候命令才是真正的执行,并且返回执行结果

2:一般事物都有rollback操作,但是redis的事物是不支持rollback操作的,比较遗憾,但是事情都有两面性,正是因为redis不支持rollback操作,所以redis内部才能保持简单而且快速

redis不支持rollback演示

在图中mset命令语法是没有问题的,成功的入到了事物中,执行之后返回结果中第一步成功执行,但是在mset的时候返回错误。

所以类似于这种错误,是需要我们在编程的过程中就避免的,而不应该到生产环境中的。

Redis事物只能检查出语法错误,如果发现语法错误,整个事物直接结束

redis的事物的语法错误

Discard其实就是在multi之后 清楚事物队列,没什么好说的

3:WATCH

WATCH key [key ...]

监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

现实中会存在这样一个问题,比如我们要完成一个incr的操作(不考虑用incr的方法),

val = GET mykey,val = val + 1,SET mykey $val

上面的这个实现在只有一个客户端的时候可以执行得很好。 但是, 当多个客户端同时对同一个键进行这样的操作时, 就会产生竞争条件。举个例子, 如果客户端 A 和 B 都读取了键原来的值, 比如10 , 那么两个客户端都会将键的值设为 11 , 但正确的结果应该是 12 才对。

有了 WATCH , 我们就可以轻松地解决这类问题了:

WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。

WATCH 的键会被监视,并会发觉这些键是否被改动过了(在下图中第2步就是改动)。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回nil-reply来表示事务已经失败。

redis的事物 watch演示

用户还可以用watch锁定多个键

Watch key1 key2 key3

使用 WATCH 实现 ZPOP

WATCH 可以用于创建 Redis 没有内置的原子操作。举个例子, 以下代码实现了原创的 ZPOP 命令, 它可以原子地弹出有序集合中分值(score)最小的元素:

WATCH zset

element = ZRANGE zset 0 0

MULTI

ZREM zset element

EXEC

程序只要重复执行这段代码, 直到 EXEC 的返回值不是nil-reply回复即可。