Redis事务深度解析:确保数据一致性的最佳实践
引言
Redis是一个开源的、基于内存的键值数据存储系统。它允许您规划一系列命令并按顺序执行,这一过程被称为事务(Transaction)。每个事务都被视为一个连续且隔离的操作,以确保数据的完整性。在事务块执行期间,客户端无法运行其他命令。
本教程将探讨如何在Redis中执行和取消事务,并提供关于事务常见陷阱的信息。
如何使用本指南
本指南以自给自足的示例形式编写,旨在作为备忘录。我们鼓励您直接跳转到与您当前任务相关的部分。
本指南中展示的命令已在运行Redis 6.0.16版本的Ubuntu 22.04服务器上进行测试。要设置类似的环境,您可以参考我们的《如何在Ubuntu 22.04上安装和保护Redis》指南中的第一步。我们将使用Redis命令行接口redis-cli
来演示这些命令的行为。如果您使用其他Redis接口(例如Redli),某些命令的精确输出可能会有所不同。
此外,您也可以选择使用托管的Redis数据库实例来测试这些命令。但请注意,根据数据库提供商允许的控制级别,本指南中的某些命令可能无法按所述方式工作。要使用Silicon Cloud托管数据库,请参考我们的托管数据库产品文档。之后,您必须安装Redli或设置TLS隧道,以便通过TLS连接到托管数据库。
运行事务
MULTI
命令告诉Redis开始一个事务块。任何后续命令都将被排队,直到执行EXEC
命令,该命令将执行所有排队的命令。
以下命令构成一个单一的事务块。第一个命令启动事务,第二个命令设置一个键key_MeaningOfLife
,其值为字符串“1”,第三个命令将其值增加1,第四个命令将其值增加40,第五个命令返回该字符串的当前值,最后一个命令执行事务块。
- MULTI
- SET key_MeaningOfLife 1
- INCR key_MeaningOfLife
- INCRBY key_MeaningOfLife 40
- GET key_MeaningOfLife
- EXEC
在运行MULTI
之后,redis-cli
将对后续的每个命令回复“QUEUED”。在运行EXEC
命令后,它将逐一显示这些命令的输出。
1) OK
2) (integer) 2
3) (integer) 42
4) “42”
事务块中包含的命令按照它们排队的顺序依次运行。Redis事务是原子性的(Atomic),这意味着事务块中的每个命令要么都会被处理(被接受为有效并排队等待执行),要么都不会被处理。然而,即使一个命令成功排队,当执行时仍然可能产生错误。在这种情况下,事务中的其他命令仍然可以运行,但Redis会跳过引起错误的那个命令。有关事务错误的详细信息,请阅读“理解事务错误”部分。
取消事务
要取消事务,请运行DISCARD
命令。这将阻止之前所有排队的命令运行。
- MULTI
- SET key_A 146
- INCRBY key_A 10
- DISCARD
OK
DISCARD
命令会将连接恢复到正常状态,告诉Redis以通常方式运行单个命令。您需要再次运行MULTI
命令来通知服务器您要开始另一个事务。
理解事务错误
有些命令是无法排队的,例如具有语法错误的命令。如果您尝试排队一个语法错误的命令,Redis将返回一个错误。
以下事务创建了一个名为key_A
的键,并尝试将其递增10。然而,INCRBY
命令中的拼写错误导致错误并关闭了该事务。
- MULTI
- SET key_A 146
- INCRBUY key_A 10
(error) ERR unknown command ‘incrbuy’
如果您在尝试排队一个带有语法错误的命令之后尝试运行EXEC
命令,您将收到另一条错误消息,告诉您事务已被丢弃。
- EXEC
(error) EXECABORT Transaction discarded because of previous errors.
在这种情况下,您需要重新启动事务块,并确保正确输入每个命令。
有些“不可能”的命令可以排队,例如在只包含字符串的键上运行INCR
命令。因为这样的命令在语法上是正确的,如果您尝试将其包含在一个事务中,Redis不会返回错误,也不会阻止您运行EXEC
。在这种情况下,队列中的所有其他命令都将被执行,但是“不可能”的命令将返回一个错误。
- MULTI
- SET key_A 146
- INCRBY key_A “ten”
- EXEC
1) OK
2) (error) ERR value is not an integer or out of range
要获取有关Redis在事务中处理错误的更多信息,请阅读官方文档。
结论
本指南详细介绍了在Redis中创建、运行和取消事务所使用的一些命令。如果您希望在本指南中了解其他相关的命令、参数或程序,请在评论中提问或提出建议。
要获取更多关于Redis命令的信息,请查看我们的教程系列《如何管理Redis数据库》。