我想乐观地“锁定”一段代码。伪代码如下:
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 都是原子的。你觉得这种方法有什么问题吗?
我想乐观地“锁定”一段代码。伪代码如下:
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 都是原子的。你觉得这种方法有什么问题吗?
这种方法存在一些问题。首先,它不会远远超过 2 个工人,因为速度越快的工人会饿死越慢。流程也缺乏原子性,这可能是也可能不是问题,具体取决于您正在运行的逻辑,但竞争条件很糟糕。最后,这里有一点观察者效应,因为你总是在增加 key_lock。
更好的方法是使用 Redis 的MULTI、EXEC和WATCH。Redis 的事务主题非常巧妙地讨论了这一点,并根据您的伪代码提供了以下示例:
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