Redis 2.6以降を使用している場合は、Luaスクリプトエンジンを使用すると、これをはるかに簡単に行うことができます。 Redisのドキュメントには次のように書かれています:
Redisスクリプトは定義上トランザクションであるため、Redisトランザクションで実行できることはすべて、スクリプトでも実行できます。通常、スクリプトはよりシンプルで高速になります。
実装は簡単です:
LUA_ACQUIRE = "return redis.call('setnx', KEYS[1], 1) == 1 and redis.call('expire', KEYS[1], KEYS[2]) and 1 or 0"
def lock(key, timeout = 3600)
if redis.eval(LUA_ACQUIRE, key, timeout) == 1
begin
yield
ensure
r.del key
end
end
end
使用法:
lock("somejob") { do_exclusive_job }