gpt4 book ai didi

redis - 为什么 StackExchange.Redis 在 transaction.ExecuteAsync() 中频繁抛出 "Unexpected response to EXEC: MultiBulk: 0"异常?

转载 作者:可可西里 更新时间:2023-11-01 11:21:44 27 4
gpt4 key购买 nike

我尝试通过代码进行调试,它似乎主要在多个客户端试图修改事务中的同一个 key 时重现。重试事务通常可以消除错误,但是首先抛出异常有什么原因吗?

我要执行的代码非常简单:

var existingValue = db.HashGetAsync(hashKey, field);
var t = db.CreateTransaction();
t.AddCondition(Condition.HashEqual(hashKey, field, existingValue));
t.HashSetAsync(hashKey, field, newValue, flags: CommandFlags.FireAndForget);
bool succeeded = await t.ExecuteAsync(); // StackExchange.Redis.RedisConnectionException thrown intermittently

最佳答案

当您尝试同时从 2 个不同的线程更新相同的 key 时,会发生此异常。如果您为每个应用程序使用一个 ConnectionMultiplexer(如推荐的那样),它只会在从不同的应用程序或主机访问 key 时发生。

当您以事务方式更新值时,如果更新失败(transaction.ExecuteAsync() 返回 false 或抛出“对 EXEC 的意外响应:MultiBulk:0 项”异常),您应该重试。

这是一个事务更新字符串值的方法:

    public async Task<string> UpdateValueAsync(string key, Func<string, string> updateAction)
{
for (int i = 0; i < UpdateRetryCount; i++)
{
var oldValue = await database.StringGetAsync(key);

if (oldValue.IsNull)
throw new InvalidOperationException(string.Format("Key \"{0}\" not found.", key));

var newValue = updateAction(oldValue);

var transaction = database.CreateTransaction();
transaction.AddCondition(Condition.StringEqual(key, oldValue));
transaction.StringSetAsync(key, newValue);

try
{
if (await transaction.ExecuteAsync())
{
return newValue;
}
}
catch (RedisConnectionException exception)
{
if (exception.Message != "Unexpected response to EXEC: MultiBulk: 0 items")
{
throw;
}
}
}

throw new InvalidOperationException(string.Format("Failed to update value in key {0}.", key));
}

关于redis - 为什么 StackExchange.Redis 在 transaction.ExecuteAsync() 中频繁抛出 "Unexpected response to EXEC: MultiBulk: 0"异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26877473/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com