stringsetasync with when.notexists返回false

mspsb9vt  于 2021-06-08  发布在  Redis
关注(0)|答案(1)|浏览(562)

我正在使用stackexchange.redis,其副本群集(3个节点)配置为使用sentinel。
我收到多个请求试图用相同的数据更新缓存,因此为了避免多次写入,我使用 When.NotExistsStringSetAsync . 我的理解是,如果密钥已经存在,那么这将阻止set发生。我在等你 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 基于我手动检查密钥是否存在的健全性检查,即使密钥不存在,也返回false。
注意:我的环境使用两个副本节点和一个主节点。stackexchange.redis版本:2.1.58

xoshrz7s

xoshrz7s1#

在这些情况下,我通常会临时增加 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);
    }
}

请告诉我进展如何!

相关问题