如何在 Redis 中运行事务

系列教程导航

本教程属于 Redis 管理系列的一部分,您可以参考以下相关指南:

  1. 如何在 Ubuntu 18.04 上安装和保护 Redis
  2. 如何连接到 Redis 数据库
  3. 如何管理 Redis 数据库和 Keys
  4. 如何在 Redis 中管理副本和客户端
  5. 如何在 Redis 中管理字符串
  6. 如何在 Redis 中管理 List
  7. 如何在 Redis 中管理 Hashes
  8. 如何在 Redis 中管理 Sets
  9. 如何在 Redis 中管理 Sorted Sets
  10. 如何在 Redis 中运行事务
  11. 如何使 Redis 中的 Key 失效
  12. 如何解决 Redis 中的故障
  13. 如何从命令行更改 Redis 的配置
  14. Redis 数据类型简介

介绍

Redis 是一个开源的内存中键值数据存储系统。Redis 允许您规划一系列命令,然后按顺序依次执行它们,这一过程称为事务(Transaction)。每个事务都被视为一个原子性且隔离的操作,以确保数据完整性。在执行事务块期间,客户端无法运行其他命令。

本教程介绍了如何执行和取消事务,并涵盖了与事务处理相关的一些常见陷阱。

如何使用本指南

本指南以包含完整示例的速查表形式编写。我们鼓励您直接跳转至与您当前任务相关的部分。

本指南中显示的命令已在运行 Redis 版本 4.0.9Ubuntu 18.04 服务器上进行了测试。要设置类似的环境,您可以按照我们的指南 如何在 Ubuntu 18.04 上安装和保护 Redis第一步进行操作。我们将通过使用 Redis 命令行界面 [redis-cli](https://blog.jsdiff.com/archives/%E5%A6%82%E4%BD%95%E5%9C%A8ubuntu1804%E4%B8%8A%E5%AE%89%E8%A3%85%E5%92%8C%E4%BF%9D%E6%8A%A4redis) 运行它们来演示这些命令的行为。请注意,如果您使用其他 Redis 界面(例如 Redli),则某些命令的确切输出可能会有所不同。

另外,您可以提供一个托管的 Redis 数据库实例来测试这些命令,但是请注意,根据数据库提供者所允许的控制级别,本指南中的某些命令可能无法按所述方式工作。要配置 DigitalOcean 托管数据库,请遵循我们的 托管数据库产品文档。然后,您必须 安装 Redli 设置 TLS 隧道 才能通过 TLS 连接到托管数据库。

运行事务

MULTI 命令告诉 Redis 开始一个事务块。在执行 EXEC 命令之前,所有后续命令都将进入排队等待状态。

以下命令形成一个事务块。第一个命令启动事务,第二个命令设置一个包含值 1 的字符串键,第三个命令将值增加 1,第四个命令将其值增加 40,第五个返回字符串的当前值,最后一个命令提交并执行事务块:

MULTI
SET key_MeaningOfLife 1
INCR key_MeaningOfLife
INCRBY key_MeaningOfLife 40
GET key_MeaningOfLife
EXEC

运行 MULTI 后,redis-cli 将对以下每个命令响应 QUEUED。运行 EXEC 命令后,它将分别显示每个命令的输出:

Output
1) OK
2) (integer) 2
3) (integer) 42
4) "42"

事务块中包含的命令按排队顺序依次运行。Redis 事务是原子性的,这意味着要么处理事务块中的每个命令(意味着它被视为有效命令并排队等待执行),要么完全不执行。但是,即使命令成功排队,执行时它仍然可能产生错误。在这种情况下,事务中的其他命令仍然可以运行,但是 Redis 将跳过导致错误的命令。有关更多详细信息,请参见 理解事务错误 部分。

取消事务

要取消事务,请运行 DISCARD 命令。这样可以防止任何先前排队的命令运行:

MULTI
SET key_A 146
INCRBY key_A 10
DISCARD
Output
OK

DISCARD 命令将连接恢复到正常状态,该状态告诉 Redis 像往常一样运行单个命令。您需要再次运行 MULTI 以告知服务器您正在开始另一个事务。

理解事务错误

某些命令可能无法排队,例如存在语法错误的命令。如果尝试对语法错误的命令进行排队,则 Redis 将返回错误。

下面的事务创建了一个名为 key_A 的键,然后尝试将其增加 10。但是,INCRBY 命令中的拼写错误导致报错并关闭了该事务:

MULTI
SET key_A 146
INCRBUY key_A 10
Output
(error) ERR unknown command 'INCRBUY'

如果在尝试将包含类似语法错误的命令放入队列后运行 EXEC 命令,则会收到另一条错误消息,告知您事务已被丢弃:

EXEC
Output
(error) EXECABORT Transaction discarded because of previous errors.

在这种情况下,您需要重新启动事务块并确保正确输入每个命令。

一些无效命令可以排队的,例如对仅包含字符串的键运行类型不匹配的命令。由于该命令在语法上是正确的,因此如果您尝试将其包含在事务中,Redis 不会返回错误,也不会阻止您运行 EXEC。在这种情况下,将执行队列中的所有其他命令,但无效的命令将返回错误:

MULTI
SET key_A 146
INCRBY key_A "ten"
EXEC
Output
1) OK
2) (error) ERR value is not an integer or out of range

有关 Redis 如何处理事务内部错误的更多信息,请参阅 关于此主题的官方文档

总结

本指南详细介绍了许多用于在 Redis 中创建、运行和取消事务的命令。如果您想在本指南中概述其他相关的命令、参数或过程,请在下面的评论中提出疑问或提出建议。

有关 Redis 命令的更多信息,请参阅 如何管理 Redis 数据库 系列教程。

说明:本教程基于 Redis 4.0.9 版本及 Ubuntu 18.04 环境编写。较新版本的 Redis 可能在命令行为或输出格式上略有差异,但核心事务机制(MULTI/EXEC/DISCARD)保持一致。