8

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

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

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

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

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

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

4

1 回答 1

15

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

选项1:

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

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

在这个例子中,multi 块内的写命令将被原子地执行,但前提key 的值在被调用后x没有改变。WATCH这称为乐观锁。如果 的值x确实发生了变化,您的应用程序将出现错误,并且需要决定下一步该做什么,这可能会使用 的新值再次尝试x

选项 2:

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

于 2013-08-27T07:06:00.380 回答