java - compareAndSet 如何在 Redis 内部工作

标签 java spring redis

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 (;;)?总是有一个迭代。

最佳答案

问:operations.watch 是否以某种方式阻止它?

是。

引自Redis documentation about transaction :

WATCH is used to provide a check-and-set (CAS) behavior to Redis transactions.

WATCHed keys are monitored in order to detect changes against them. If at least one watched key is modified before the EXEC command, the whole transaction aborts, and EXEC returns a Null reply to notify that the transaction failed.

您可以从该文档中了解有关 Redis 事务的更多信息。

问:为什么要 (;;)?总是有一个迭代。

您发布的代码似乎很旧。来自 Google 的缓存 this url ,我看到你提供的代码可以追溯到 2012 年 10 月 15 日!

最新的代码看起来很不一样:

关于java - compareAndSet 如何在 Redis 内部工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54234192/

相关文章:

java - lucene 在服务断开之前不会调用操作

java - 向后拼写单词

hibernate - 一起运行时 Maven Spring 测试失败,但单独成功(ehcache 关闭,IllegalTransactionStateException)

java - 有没有办法禁用 Thymeleaf,或者只为某些 REST 调用启用?

node.js - 我应该如何在redis中存储数组?

node.js - RedisStore - 错误回调

java - Servlet 不应该有可变的实例字段误报 Spring Autowiring (squid :S2226)

java - java.util.Stack 或 java.util.Queue 有什么线程安全问题

java - 使用 Spring 的密码加密/解密

amazon-web-services - 无法将 redis-cli 与亚马逊 elasticache 连接