【问题标题】:Transactions in Redis with read operationsRedis 中具有读取操作的事务
【发布时间】:2013-08-29 10:15:16
【问题描述】:

使用 Redis,我想执行一个原子命令序列,即我需要保证在执行序列时没有其他客户端会在数据库中执行更改。

如果我只使用 write 命令,我可以使用 MULTIEXEC 语句来确保使用事务的原子性。但是,我也想在我的事务中使用 read 命令。因此我不能使用MULTI,因为读取命令也在排队!

基本上,以原子方式,我需要执行以下操作:

  1. 从数据库中读取x
  2. 基于x,将f(x)存入数据库。

1. 和 2. 都应该是单个原子事务的一部分。

有没有简单的方法可以做到这一点?

【问题讨论】:

标签: transactions redis atomic


【解决方案1】:

您的问题有两个很好的解决方案。

选项 1:

您需要在正在读取的密钥上发出WATCH。您的交易将如下所示:

WATCH x
x = GET x
MULTI
SET y, f(x)
EXEC

在本例中,multi 块内的写入命令将自动执行,但如果键 x 的值在调用 WATCH 后未更改。这称为乐观锁。如果x 的值确实发生了变化,您的应用程序将会出错,并且需要决定下一步该做什么,这可能会使用x 的新值再次尝试。

选项 2:

Redis 现在支持 lua 脚本,并且 lua 脚本以原子方式执行。如果您可以将您的逻辑封装到一个 lua 脚本中,您可以读取您的密钥,运行您的 f(x) 逻辑,并以原子方式存储结果。根据您正在执行的逻辑,这可能很棘手,甚至是不可选择的。您甚至可能不得不通过将值直接硬编码到您希望 redis 执行的脚本中来进行丑陋的 hack,例如将值传递给 lua。也就是说,如果你让它工作,这个方法应该是可靠和高性能的,你不必处理处理 EXEC 故障。

【讨论】:

  • 选项 1 非常适合我的需求,因为迭代重试操作似乎是一个合理的解决方案。目前,与我提供的示例相比,我的应用程序逻辑要复杂得多,但我一定会看看 Lua。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
  • 2020-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多