Redis中的事务与读取操作

时间:2013-08-26 20:18:12

标签: transactions redis atomicity

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

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

基本上,以原子方式,我需要做以下事情:

  1. 从数据库中读取x
  2. 基于x,将f(x)存储到数据库中。
  3. 1.和2.应该是单个原子事务的一部分。

    有一种简单的方法可以做到吗?

1 个答案:

答案 0 :(得分:10)

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

选项1:

您需要在正在阅读的密钥上发出WATCH。您的交易看起来像这样:

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

在此示例中,多块内的写命令将以原子方式执行,但如果自调用x后键WATCH的值未发生更改,则。这称为乐观锁。如果x的值确实发生了变化,那么您的应用程序将会出现错误,需要决定下一步该做什么,这可能会使用x的新值重新尝试。

选项2:

Redis现在支持lua脚本,lua脚本以原子方式执行。如果您可以将逻辑封装到lua脚本中,则可以读取密钥,运行f(x)逻辑,并以原子方式存储结果。根据您正在执行的逻辑,这可能很棘手甚至是非选项。您甚至可能必须通过将它们直接硬编码到您希望redis执行的脚本中来执行丑陋的黑客操作,例如将值传递给lua。也就是说,如果你使用它,这个方法应该是可靠和高效的,而且你不必处理EXEC失败的处理。