如何解决当键不存在时,带有When.NotExists的StringSetAsync返回false
我正在将StackExchange.Redis与配置为使用Sentinel的副本群集(3个节点)一起使用。
我收到多个尝试使用相同数据更新缓存的请求,因此为了避免多次写入,我在When.NotExists
中使用了StringSetAsync
。我的理解是,如果密钥已经存在,这将防止发生该集合。我希望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。
注意: 我的环境使用2个副本节点和1个主节点。 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);
}
}
请告诉我情况如何!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。