c# - 当键不存在时,带有 When.NotExists 的 StringSetAsync 返回 false

标签 c# redis stackexchange.redis sentinel redis-sentinel

我将 StackExchange.Redis 与配置为使用 Sentinel 的副本集群(3 个节点)一起使用。
我收到多个尝试使用相同数据更新缓存的请求,因此为了避免多次写入,我使用了 When.NotExistsStringSetAsync .我的理解是,如果 key 已经存在,这将防止设置发生。我在期待 StringSetAsync仅在集合实际发生的情况下返回 true。
例子:

var inserted = await connectionMultiplexer.GetDatabase().StringSetAsync("my-key", "my-value", myTimeout, When.NotExists);

if(inserted == false)
{
  var keyExists = await connectionMultiplexer.GetDatabase().KeyExistsAsync("my-key");
  if(keyExists == false)
  {
    // I end up here, which I assumed should not happen. 
  }
}

令我惊讶的是,我看到了 StringSetAsync即使基于我手动检查 key 是否存在的健全性检查, key 还不存在,也会返回 false。
笔记:
我的环境使用 2 个副本节点和一个主节点。
StackExchange.Redis 版本:2.1.58

最佳答案

在这些情况下,我通常做的是暂时增加 expiry (myTimeout)参数设置为更大的值只是为了从等式中删除超时。接下来的步骤是检查应用程序和数据库服务器之间所有系统边界的访问权限。
另请记住,如果操作因超时或其他类型的失败而引发异常,则取决于您应用 async/await 的方式。堆栈,在某些情况下无法向调用线程抛出超时异常,需要查询Task.Exception聚合以检查问题的根源。
结果是false我觉得很可疑( boolean 的默认值)并且您可能在 Task.Exception 中找到了问题的答案总计的。
要找出答案,您可以同步尝试:

try
{
    var inserted = connectionMultiplexer.GetDatabase().StringSetAsync("my-key", "my-value", myTimeout, When.NotExists).Result;
    if (inserted == false)
    {
        var keyExists = connectionMultiplexer.GetDatabase().KeyExistsAsync("my-key").Result;
        if (keyExists == false)
        {
            // I end up here, which I assumed should not happen. 
        }
    }
}
catch (AggregateException aex)
{
    foreach (var ex in aex.InnerExceptions)
    {
        Console.WriteLine(ex);
    }
}
请告诉我进展如何!

关于c# - 当键不存在时,带有 When.NotExists 的 StringSetAsync 返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64210570/

相关文章:

redis - ElastiCache Redis 服务器

c# - 没有连接可用于服务此操作 : ZRANGEBYSCORE redis

c# - StackExchange.Redis - 是否可以确定端点的优先级?

c# - Json.NET 按深度和属性序列化

c# - 如何在 C# 中显示来自 SAP RFC 的 pdf

c# - 在 C# 中编码(marshal) C++ "char**"

ubuntu - Redis 进程被 OS 杀死,是否存在 bug?

c# - 参数化线程,理解lambda表达式

c# - 外部(互联网)Pub Sub

c# - StackExchange.Redis 事务