Ако използвате 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 }