Redis事务

开启事务 multi命令

multi 命令不能嵌套使用,如果已经开启了事务的情况下,再执行 multi 命令,会报错:ERR MULTI calls can not be nested

执行相关命令入列

Redis事务以MULTI开始,中间添加多种命令,这些命令不会立即执行,而是被放入到一个队列中,当执行EXEC时,队列中的所有命令被依次执行

即使事务队列中某个命令在执行期间发生了错误(语法没错,但是可能设置的数据类型不支持),事务也会继续执行,直到事务队列中所有命令执行完成。也就是执行期间中途某个命令错误并不会导致数据全部恢复事务开启前,只是错误的那个命令没执行。

但如果是入列命令错误,比如没有设置命令语法错误,没有添加value,事务就不执行。

重复执行 multi 会导致入列错误,但不会终止事务,最终查询的结果是事务执行成功了。除了重复执行 multi 命令,还有在事务状态下执行 watch 也是同样的效果。
 
不支持事务回滚,指的是不支持运行时错误的事务回滚。

执行事务 exec/放弃事务 discard

 

监控 watch命令

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

watch 命令只能在客户端开启事务之前执行,在事务中执行 watch 命令会引发错误,但不会造成整个事务失败。

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

watch 命令监控时,即使把原对象的值重新赋值给了原对象,这个时候 watch 命令也会认为监控对象还是被修改了。

事务错误&回滚

watch监控的元素在当前事务提交之前,被放入到另外一个事务的队列中,但并未执行exec,则当前事务可正常提交

事务执行中的错误分为以下三类:

  • 执行时才会出现的错误(简称:执行时错误),不会终止整个事务;
  • 入列时错误(语法错误),会终止整个事务
  • watch的值在exec前变化,事务回滚

举例子:

MULTI

SET key1 value1

SET key2 value2

DIV key3 0

EXEC

在这个例子中,我们使用了 Redis 的事务命令 MULTI 和 EXEC 来包裹多个命令。在事务中,我们首先设置了 key1 和 key2 的值,然后执行了一个除法操作 DIV key3 0,其中除数为 0。 在传统的数据库中,如果一个事务中的某个命令失败,整个事务会被回滚,即之前执行的命令都会被撤销。但是在 Redis 中,事务的执行方式略有不同。 当执行到 DIV key3 0 这个命令时,由于除数为 0,会导致一个错误。但是 Redis 并不会立即回滚整个事务,而是继续执行余下的命令。在这个例子中,事务会继续执行 EXEC 命令,返回一个包含错误信息的结果集。 这种行为是由 Redis 的设计决策所决定的。Redis 的事务是基于乐观锁的,并不会对命令进行实际的执行,而是将它们放入一个队列中。只有在执行 EXEC 命令时,Redis 才会逐个执行队列中的命令。因此,即使在事务中某个命令失败,Redis 仍然会继续执行余下的命令。 需要注意的是,虽然 Redis 不会回滚整个事务,但是在事务中的命令执行失败后,对数据的修改是不会生效的。也就是说,在上述例子中,key1 和 key2 的值会被成功设置,但是 key3 的值不会被修改。因此,开发者在使用 Redis 事务时需要注意处理命令执行失败的情况。

 
posted @   klm-kain  阅读(92)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示