我在群集ASP.Net核心服务器上使用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
我的印象是交易只有在条件不满足时才会失败,这是真的吗?
查看网络和性能指标,没有超时或高内存使用可能有助于此。
编辑:不幸的是,在更高的负载下,这种方法开始分崩离析。有时,交易需要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);
}
使用bool删除而不是var删除