源地址:https://www.digitalocean.com/community/cheatsheets/how-to-run-transactions-in-redis
作者:Mark Drake

简介

Redis 是一个开源的、运行在内存中的键值数据库。Redis 允许你设计一连串的命令,并一个接一个地运行它们,这种程序被称为事务。客户端不可能在事务块执行时运行命令,这确保了事务被视为一个单独的隔离操作。

本教程介绍了如何执行和取消事务,还包括一些通常与事务有关的陷阱的信息。

如何使用这个教程

这个教程是以小抄(Cheat Sheet)的形式写的,有对应的例子。我们鼓励你直接跳转到和你要完成的任务相关的章节进行阅读。

这个教程中的命令在 Ubuntu 18.04 中的 Redis 4.0.9 版本完成测试。如果你需要建设一个同样的环境,可以参考我们的 如何在 Ubuntu 18.04 上安装并加固 Redis 中的 Step 1 来安装 Redis。我们将通过 Redis 命令行界面redis-cli运行这些命令,来演示这些命令的行为。请注意,如果你使用不同的 Redis 工具--例如Redli —— 某些命令的实际输出可能有所不同。

此外,你还可以使用一个代管的 Redis 数据库实例来测试这些命令。但需要注意的是,根据你的数据库服务提供商的限制,这个教程中的某些命令可能运行效果和教程不一致。如果想要使用 DigitalOcean 提供的代管数据库,可以查看我们的代管数据库产品文档。使用代管 Redis 数据库实例时,你必须安装 Redli设置 TLS 隧道 来通过 TLS 链接到代管数据库。

运行事务

multi 命令告诉 Redis 开始一个事务块。任何后续命令都将进入队列,直到您运行 exec 命令,该命令将执行它们。

以下命令形成单个事务块。第一个命令启动事务,第二个设置一个 key 保存一个值为 1 的字符串,第三个将值增加 1,第四个将其值增加 40,第五个返回字符串的当前值,并且 最后一个执行事务块:

127.0.0.1:6379>  multi
127.0.0.1:6379>  set key_MeaningOfLife 1
127.0.0.1:6379>  incr key_MeaningOfLife
127.0.0.1:6379>  incrby key_MeaningOfLife 40
127.0.0.1:6379>  get key_MeaningOfLife
127.0.0.1:6379>  exec

运行 multi 后,redis-cli 将使用 QUEUED 响应以下每个命令。运行 exec 命令后,它将分别显示每个命令的输出:

输出

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

事务块中包含的命令按照它们排队的顺序依次运行。Redis 事务是原子化的,这意味着事务块中的每个命令都被会处理(意味着它被接受为有效并排队等待执行)或者没有。但是,即使命令成功排队,执行时仍可能产生错误。在这种情况下,事务中的其他命令仍然可以运行,但 Redis 会跳过导致错误的命令。更多信息参阅 理解事务错误 部分。

取消事务

想要取消一个事务,运行 discard 命令。它将阻止任何之前排队的命令运行:

127.0.0.1:6379>   multi
127.0.0.1:6379>  set key_A 146
127.0.0.1:6379>  incrby key_A 10
127.0.0.1:6379>  discard

输出

 OK

discard 命令将连接返回到正常状态,这告诉 Redis 像往常一样运行单个命令。你需要再次运行multi来告诉服务器你正在开始另一个事务。

理解事务错误

某些命令可能无法排队,例如有语法错误的命令。如果您尝试将语法不正确的命令排队,Redis 将返回错误。

以下事务创建了一个名为“key_A”的键,然后尝试将其递增 10。但是,“incrby”命令中的拼写错误导致错误并关闭事务:

127.0.0.1:6379>  multi
127.0.0.1:6379>  set key_A 146
127.0.0.1:6379>  incrbuy key_A 10

输出

 (error) ERR unknown command 'incrbuy'

如果您在尝试将具有此类语法错误的命令排队后尝试运行“exec”命令,您将收到另一条错误消息,告诉您该事务已被丢弃:

127.0.0.1:6379>  exec

输出

 (error) EXECABORT Transaction discarded because of previous errors.

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

一些不可能的命令 可能 会排队,例如在只包含字符串的键上运行 incr。因为这样的命令在语法上是正确的,所以如果你尝试将它包含在事务中,Redis 不会返回错误,也不会阻止你运行 exec。在这种情况下,队列中的所有其他命令都将被执行,但不可能的命令将返回错误:

127.0.0.1:6379>  multi
127.0.0.1:6379>  set key_A 146
127.0.0.1:6379>  incrby key_A "ten"
127.0.0.1:6379>  exec

输出

1) OK
2) (error) ERR value is not an integer or out of range

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

总结

本指南详细介绍了使用的一些命令 在 Redis 中创建、运行和取消事务。