Redis事务深入解析和使用 (2)

执行命令解释如下图所示:

image.png


可以看出,重复执行 multi 会导致入列错误,但不会终止事务,最终查询的结果是事务执行成功了。除了重复执行 multi 命令,还有在事务状态下执行 watch 也是同样的效果,下文会详细讲解关于 watch 的内容。

3)入列错误不会导致事务结束

示例代码如下:

> get k "v2" > multi OK > set k v3 QUEUED > set k (error) ERR wrong number of arguments for 'set' command > exec (error) EXECABORT Transaction discarded because of previous errors. > get k "v2"

执行命令解释如下图所示:

image.png

4)为什么不支持事务回滚?

Redis 官方文档的解释如下:

If you have a relational databases background, the fact that Redis commands can fail during a transaction, but still Redis will execute the rest of the transaction instead of rolling back, may look odd to you.
However there are good opinions for this behavior:

Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.

Redis is internally simplified and faster because it does not need the ability to roll back.

An argument against Redis point of view is that bugs happen, however it should be noted that in general the roll back does not save you from programming errors. For instance if a query increments a key by 2 instead of 1, or increments the wrong key, there is no way for a rollback mechanism to help. Given that no one can save the programmer from his or her errors, and that the kind of errors required for a Redis command to fail are unlikely to enter in production, we selected the simpler and faster approach of not supporting roll backs on errors.

大概的意思是,作者不支持事务回滚的原因有以下两个:

他认为 Redis 事务的执行时,错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以他认为没有必要为 Redis 开发事务回滚功能;

不支持事务回滚是因为这种复杂的功能和 Redis 追求的简单高效的设计主旨不符合。

这里不支持事务回滚,指的是不支持运行时错误的事务回滚。

4.监控

watch 命令用于客户端并发情况下,为事务提供一个乐观锁(CAS,Check And Set),也就是可以用 watch 命令来监控一个或多个变量,如果在事务的过程中,某个监控项被修改了,那么整个事务就会终止执行
watch 基本语法如下:

watch key [key ...]

watch 示例代码如下:

> watch k OK > multi OK > set k v2 QUEUED > exec (nil) > get k "v"

从以上命令可以看出,如果 exec 返回的结果是 nil 时,表示 watch 监控的对象在事务执行的过程中被修改了。从 get k 的结果也可以看出,在事务中设置的值 set k v2 并未正常执行。
执行流程如下图所示:

image.png


注意: watch 命令只能在客户端开启事务之前执行,在事务中执行 watch 命令会引发错误,但不会造成整个事务失败,如下代码所示:

> multi OK > set k v3 QUEUED > watch k (error) ERR WATCH inside MULTI is not allowed > exec 1) OK > get k "v3"

执行命令解释如下图所示:

image.png


unwatch 命令用于清除所有之前监控的所有对象(键值对)。
unwatch 示例如下所示:

> set k v OK > watch k OK > multi OK > unwatch QUEUED > set k v2 QUEUED > exec 1) OK 2) OK > get k "v2"

可以看出,即使在事务的执行过程中,k 值被修改了,因为调用了 unwatch 命令,整个事务依然会顺利执行。

5.事务在程序中使用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzyfg.html