我在ASP.Net Core群集服务器上使用Stackexchange.Redis,并且在处理事务时遇到了麻烦。
以下代码应该从两个哈希(“ 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
我的印象是,只有在不满足交易条件的情况下交易才会失败,是真的吗?
查看网络和性能指标,没有超时或高内存使用情况可能对此造成影响。
答案 0 :(得分:0)
编辑:不幸的是,在更高的负载下,这种方法开始崩溃。有时,一次事务需要进行50次尝试,这会损害性能并花费很长时间。仍在寻找更好的解决方案。
我实施了一种变通方法,效果很好。
对于!deleted && hashACondition.WasSatisfied && hashBCondition.WasSatisfied
,我只是立即重试删除操作,最多4次。
根据测试,此问题已基本解决。在6000次尝试中,有430次需要重试,62次需要重试两次,依此类推。
对我来说,这仍然像是redis或stackexchange.redis中的错误。听到一个比我更了解的人会很高兴!
答案 1 :(得分:-1)
由于受声誉的限制,我无法添加评论,因此您可以尝试一下以查看它是否对您有用:
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);
}
使用已删除布尔值而不是var删除