Оптимистичная блокировка с помощью 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
Другие вопросы по тегам