Замок на ключе в кластере Hazelcast
Я пишу распределенное приложение, использующее Hazelcast(стандарт JCache) для кэширования.
У меня есть случай использования, когда я должен поставить блокировку на определенный ключ в кластере, чтобы предотвратить вызовы во время обновления.
- thread1: получить item1 для изменения конфигурации (поставить блокировку)
- поток 2: получить элемент 1 для обновления.
- thread2: поместите item1 с обновлением и новой отметкой времени.
- поток1: положить элемент1 со старым значением и отметкой времени
Я знаю, что в EhCache есть нечто очень похожее, оно называется acquReadLockOnKey(ключ объекта).
Как я могу добиться такой блокировки с помощью JCache и / или Hazelcast?
2 ответа
Я бы предложил использовать аналогичные операции CAS (Compare And Set) (например, ConcurrentMap::replace) и использовать оптимистический шаблон блокировки, который сам по себе не является реальной блокировкой.
while(true) {
// Get the old value
T oldValue = map.get(key);
// Create the new value based on the "known old state"
T newValue = createNewValue(oldValue);
// Try to atomically exchange to the new value, if oldValue is still valid
if (map.replace(key, oldValue, newValue) break;
// If oldValue isn't valid anymore, retry
}
В большинстве случаев, когда нет высокого уровня конкуренции, это лучший альтернативный вариант по сравнению с реальной блокировкой. Он решает большинство проблем чтения-изменения-записи и не требует, чтобы классы EntryProcessor были развернуты / доступны в кластере.
Посмотрите на Entry Processor, который выполняет операции обновления над записями в кэше атомарно и без блокировки.