spring-data-redis
модуль содержит RedisAtomicLong
класс.
В этом классе вы можете увидеть
public boolean compareAndSet(long expect, long update) {
return generalOps.execute(new SessionCallback<Boolean>() {
@Override
@SuppressWarnings("unchecked")
public Boolean execute(RedisOperations operations) {
for (;;) {
operations.watch(Collections.singleton(key));
if (expect == get()) {
generalOps.multi();
set(update);
if (operations.exec() != null) {
return true;
}
}
{
return false;
}
}
}
});
}
У меня вопрос, почему это работает?
generalOps.multi()
начинает транзакцию после вызова get()
. Это означает, что существует вероятность того, что два разных потока (или даже клиента) могут изменить значение, и оба они преуспеют.
operations.watch
это как-то предотвратить? JavaDoc не объясняет назначение этого метода.
PS: незначительный вопрос: почему for (;;)
? Всегда есть одна итерация.