我在核心服务器的集群上使用Stackexchange.Redis ASP.Net 并且遇到了一些事务问题。
下面的代码应该从两个哈希"HashA"和"HashB"中删除带有键"hashItemID"的字段,但前提是它存在于两者中:
var hashAKey = "HashA";
var hashBKey = "HashB";
var id = "hashItemID";
var tran = redis.Database.CreateTransaction();
// Only delete the item if it exists in both hashes
var hashBCondition = tran.AddCondition(Condition.HashExists(hashBKey, id));
var hashACondition = tran.AddCondition(Condition.HashExists(hashAKey, id));
tran.HashDeleteAsync(hashBKey, id);
tran.HashDeleteAsync(hashAKey, id);
var deleted = await tran.ExecuteAsync();
if (!deleted)
{
logger.LogWarning("Failed to delete '{ID}'. HashAResult: {A}, HashBResult: {B}", id, hashACondition.WasSatisfied, hashBCondition.WasSatisfied);
}
有时,此代码会失败并显示日志:
Failed to delete 'hashItemID'. HashAResult: True, HashBResult: True
我的印象是,交易只有在不满足条件的情况下才会失败,这是真的吗?
查看网络和性能指标,没有超时或高内存使用率可能导致这种情况。
编辑:不幸的是,在更高的负载下,这种方法开始分崩离析。有时,一笔交易需要 50 次尝试,这会损害性能并花费很长时间。仍在寻找更好的解决方案。
我实施了一个做得足够好的解决方法。
如果是!deleted && hashACondition.WasSatisfied && hashBCondition.WasSatisfied
,我只是立即重试删除,最多 4 次。
根据测试,这基本上已经修复了它。在 6000 次尝试中,430 次需要重试一次,62 次需要重试两次,依此类推。
不过,这对我来说仍然是 redis 或 stackexchange.redis 中的一个错误。很高兴听到比我更了解的人的声音!
由于声誉限制我无法添加评论,您可以尝试此操作以查看它是否适合您:
var hashAKey = "HashA";
var hashBKey = "HashB";
var id = "hashItemID";
var tran = redis.Database.CreateTransaction();
// Only delete the item if it exists in both hashes
var hashBCondition = tran.AddCondition(Condition.HashExists(hashBKey, id));
var hashACondition = tran.AddCondition(Condition.HashExists(hashAKey, id));
tran.HashDeleteAsync(hashBKey, id);
tran.HashDeleteAsync(hashAKey, id);
bool deleted = await tran.ExecuteAsync();
if (!deleted)
{
logger.LogWarning("Failed to delete '{ID}'. HashAResult: {A}, HashBResult: {B}", id, hashACondition.WasSatisfied, hashBCondition.WasSatisfied);
}
使用删除的布尔值而不是删除的变量