Оптимистичная блокировка с помощью redis с использованием GET и INCR
Я хочу "заблокировать" блок кода оптимистично. код psuedo выглядит следующим образом:
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 ответ
Есть несколько проблем с этим подходом. Во-первых, он не будет превышать 2 рабочих, так как чем быстрее будут голодать, тем медленнее. В потоке также отсутствует атомарность, что может или не может быть проблемой в зависимости от логики, которую вы используете, но условия гонки неприятные. Наконец, здесь присутствует небольшой эффект наблюдателя, поскольку вы всегда ВКЛЮЧАЕТЕ key_lock.
Лучшим подходом было бы использовать Redis ' MULTI, EXEC и WATCH. В разделе " Транзакции" Redis обсуждается это довольно аккуратно и приводится следующий пример, основанный на вашем коде psuedo:
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