使用GET和INCR使用redis进行乐观锁定

时间:2014-05-14 11:24:49

标签: python redis optimistic-locking optimistic-concurrency

我想乐观地“锁定”一段代码。 伪代码如下:

revision = GET('lock_key') # default as 0
{
<<block of code>>
}
new_revision = INCR('lock_key')
if new_revision != revision + 1:
    raise Exception # now retry or whatever

这对我来说很好,因为INCR和GET都是原子的。 你觉得这种方法有什么问题吗?

1 个答案:

答案 0 :(得分:4)

这种方法存在一些问题。首先,它不会远远超过2名工人,因为速度较快的人会挨饿。流程也缺乏原子性,这可能是也可能不是一个问题,这取决于你正在运行的逻辑,但竞争条件是令人讨厌的。最后,这里有一些observer effect,因为你总是INCRing key_lock。

更好的方法是使用Redis'MULTIEXECWATCH。 Redis'transactions topic非常巧妙地讨论了这个问题,并根据您的伪代码提供了以下示例:

WATCH('lock_key')
revision = GET('lock_key') # default as 0
{
    <<block of code>>
}

MULTI()
new_revision = INCR('lock_key')
if EXEC() is None:
  raise Exception # now retry or whatever