源地址: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 中创建、运行和取消事务。