Транзакции не выполняются, когда все условия выполняются в StackExchange.Redis - PullRequest
0 голосов
/ 01 сентября 2018

Я использую Stackexchange.Redis на кластерных серверах ASP.Net Core, и у меня возникают проблемы с транзакциями.

Следующий код должен удалить поле с ключом "hashItemID" из двух хешей, "HashA" и "HashB", но только если оно существует в обоих:

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

У меня сложилось впечатление, что транзакции терпят неудачу, только если их условия не выполняются, это правда?

Если посмотреть на показатели сети и производительности, то здесь нет ни таймаутов, ни большого использования памяти.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

РЕДАКТИРОВАТЬ: К сожалению, при более высоких нагрузках этот подход начал разваливаться. Иногда транзакция требует 50 попыток, что снижает производительность и занимает много времени. Все еще ищу лучшее решение.

Я реализовал обходной путь, который делает достаточно хорошую работу.

В случае !deleted && hashACondition.WasSatisfied && hashBCondition.WasSatisfied я просто немедленно повторяю попытку удаления, до 4 раз.

Согласно тестам, в основном это исправлено. Из 6000 попыток 430 необходимо повторить один раз, 62 - дважды, и т. Д.

Мне все еще кажется, что это ошибка в redis или stackexchange.redis. Было бы приятно услышать от кого-то, кто знает лучше меня!

0 голосов
/ 01 сентября 2018

Поскольку я не могу добавлять комментарии из-за ограничений в репутации, вы можете попробовать это, чтобы увидеть, работает ли он для вас или нет:

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 удалено

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...