当您尝试同时从 2 个不同的线程更新同一个键时,会发生此异常。如果您为每个应用程序使用一个 ConnectionMultiplexer(如推荐的那样),则仅当从不同的应用程序或主机访问密钥时才会发生。
当您以事务方式更新值时,如果更新失败,您应该重试(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));
}