redis中控制事务的常用命令有哪些

57次阅读
没有评论

共计 2495 个字符,预计需要花费 7 分钟才能阅读完成。

自动写代码机器人,免费开通

丸趣 TV 小编给大家分享一下 redis 中控制事务的常用命令有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

相关命令介绍:

redis 中控制事务的常用命令有哪些

注意:

——MULTI,EXEC,DISCARD 才是显式开启并控制事务的常用命令,可类比关系型数据库中的  BEGAIN,COMMIT,ROLLBACK(事实上,差距很大);

——WATCH 命令的使用是为了解决 事务并发 产生的不可重复读和幻读的问题(简单理解为给 Key 加锁);

Redis 事务

MULTI, EXEC, DISCARD and WATCH 是 Redis 事务的基础。用来显式开启并控制一个事务,它们允许在一个步骤中执行一组命令。并提供两个重要的保证:

事务中的所有命令都会被序列化并按顺序执行。在执行 Redis 事务的过程中,不会出现由另一个客户端发出的请求。这保证命令队列 作为一个单独的原子操作被执行。

队列中的命令要么全部被处理,要么全部被忽略。EXEC 命令触发事务中所有命令的执行,因此,当客户端在事务上下文中失去与服务器的连接,如果发生在调用 MULTI 命令之前,则不执行任何 commands;如果在此之前 EXEC 命令被调用,则所有的 commands 都被执行。

同时,redis 使用 AOF(append-only file),使用一个额外的 write 操作将事务写入磁盘。如果发生宕机,进程奔溃等情况,可以使用 redis-check-aof tool 修复 append-only file,使服务正常启动,并恢复部分操作。

用法

使用 MULTI 命令显式开启 Redis 事务。该命令总是以 OK 回应。此时用户可以发出多个命令,Redis 不会执行这些命令,而是将它们排队。EXEC 被调用后,所有的命令都会被执行。而调用 DISCARD 可以清除事务中的 commands 队列并退出事务。

以下示例以原子方式,递增键 foo 和 bar。

MULTI
 INCR foo
QUEUED
 INCR bar
QUEUED
 EXEC
1)(整数)1
2)(整数)1

从上面的命令执行中可以看出,EXEC 返回一个数组,其中每个元素都是事务中单个命令的返回结果,而且顺序与命令的发出顺序相同。
当 Redis 连接处于 MULTI 请求的上下文中时,所有命令将以字符串 QUEUED(从 Redis 协议的角度作为状态回复发送)作为回复,并在命令队列中排队。只有 EXEC 被调用时,排队的命令才会被执行,此时才会有真正的返回结果。

事务中的错误

事务期间,可能会遇到两种命令错误:

在调用 EXEC 命令之前出现错误(COMMAND 排队失败)。例如,命令可能存在语法错误(参数数量错误,错误的命令名称 …);或者可能存在某些关键条件,如内存不足的情况(如果服务器使用 maxmemory 指令做了内存限制)。

客户端会在 EXEC 调用之前检测第一种错误。通过检查排队命令的状态回复(*** 注意:这里是指排队的状态回复,而不是执行结果 ***),如果命令使用 QUEUED 进行响应,则它已正确排队,否则 Redis 将返回错误。如果排队命令时发生错误,大多数客户端将中止该事务并清除命令队列。然而:

在 Redis 2.6.5 之前,这种情况下,在 EXEC 命令调用后,客户端会执行命令的子集(成功排队的命令)而忽略之前的错误。从 Redis 2.6.5 开始,服务端会记住在累积命令期间发生的错误,当 EXEC 命令调用时,将拒绝执行事务,并返回这些错误,同时自动清除命令队列。示例如下:

MULTI
 INCR a b c
-ERR wrong number of arguments for  incr  command

这是由于 INCR 命令的语法错误,将在调用 EXEC 之前被检测出来,并终止事务(version2.6.5+)。

在调用 EXEC 命令之后出现错误。例如,使用错误的值对某个 key 执行操作(如针对 String 值调用 List 操作)

EXEC 命令执行之后发生的错误并不会被特殊对待:即使事务中的某些命令执行失败,其他命令仍会被正常执行。

示例如下:

MULTI
 SET a 3
+QUEUED
 LPOP a
+QUEUED
 EXEC
-ERR Operation against a key holding the wrong kind of value

EXEC 返回一个包含两个元素的字符串数组,一个元素是 OK,另一个是 -ERR……。能否将错误合理的反馈给用户这取决于客户端 library(如:Spring-data-redis.redisTemplate) 的自身实现。需要注意的是,即使命令失败,队列中的所有其他命令也会被处理 —-Redis 不会停止命令的处理。

Redis 事务不支持 Rollback(重点)

事实上 Redis 命令在事务执行时可能会失败,但仍会继续执行剩余命令而不是 Rollback(事务回滚)。如果你使用过关系数据库,这种情况可能会让你感到很奇怪。然而针对这种情况具备很好的解释:

Redis 命令可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类型操作某个 Key:这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。(这番话,彻底甩锅,“都是你们自己编程错误,与我们无关”。)由于不必支持 Rollback,Redis 内部简洁并且更加高效。

“如果错误就是发生了呢?”这是一个反对 Redis 观点的争论。然而应该指出的是,通常情况下,回滚并不能挽救编程错误。鉴于没有人能够挽救程序员的错误,并且 Redis 命令失败所需的错误类型不太可能进入生产环境,所以我们选择了不支持错误回滚(Rollback)这种更简单快捷的方法。

清除命令队列

DISCARD 被用来中止事务。事务中的所有命令将不会被执行, 连接将恢复正常状态。

 SET foo 1
  MULTI
  INCR foo
QUEUED
  DISCARD
  GET foo
 1

看完了这篇文章,相信你对“redis 中控制事务的常用命令有哪些”有了一定的了解,如果想了解更多相关知识,欢迎关注丸趣 TV 行业资讯频道,感谢各位的阅读!

向 AI 问一下细节

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-04发表,共计2495字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)