我想乐观地“锁定”一段代码。 伪代码如下:
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都是原子的。 你觉得这种方法有什么问题吗?
答案 0 :(得分:4)
这种方法存在一些问题。首先,它不会远远超过2名工人,因为速度较快的人会挨饿。流程也缺乏原子性,这可能是也可能不是一个问题,这取决于你正在运行的逻辑,但竞争条件是令人讨厌的。最后,这里有一些observer effect,因为你总是INCRing key_lock。
更好的方法是使用Redis'MULTI,EXEC和WATCH。 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