StackExchange.Redis: пара вопросов о транзакциях

У меня есть несколько вопросов об использовании транзакций из StackExchange.Redis:

  1. Разрешено ли выполнять команды в транзакции, которые потенциально могут быть нацелены на разные узлы в среде кластера? Скажем, ключ первой команды имеет хэштег {1}, а ключ второй команды имеет хэштег {2}.
  2. Когда транзакция Execute()/ExecuteAsync() возвращает false? Только когда поставленные условия не были соблюдены? Может ли он вернуть false, если не было задано никаких условий?
  3. Если произойдет какая-то сетевая или внутренняя ошибка Redis, Execute()/ExecuteAsync() выкинет или просто вернет false? Должен ли я также проверять задачи команд (при условии, что команды полностью верны и обычно не должны вызывать броски) или они будут просто отменены?

К сожалению, документ не объясняет # 2 и # 3 в деталях.


person andreycha    schedule 09.02.2018    source источник


Ответы (2)


Я немного покопался в исходном коде StackExchange.Redis и поигрался с драйвером, вот мои наблюдения:

  • фактического взаимодействия не происходит, когда вы вызываете методы операции для экземпляра ITransaction
  • драйвер начинает общаться с Redis только тогда, когда вы вызываете Execute()/ExecuteAsync()

Ответы выглядят следующим образом:

  1. Как упоминал @royi-mindel, все ключи в транзакции должны быть нацелены на один и тот же слот. В противном случае вы получите исключение «Многоклавишные операции должны включать один слот».
  2. Execute()/ExecuteAsync() возвращает false в двух случаях: когда транзакция была отклонена из-за невыполнения условий и когда драйвер не смог поставить команду в очередь (например, из-за OOM сервера). Все командные задачи будут помечены как отмененные. Также Execute()/ExecuteAsync() не возвращает false, если одна из команд не удалась во время выполнения (например, из-за операции неправильного типа).
  3. В случае возникновения какой-либо проблемы с сетью Execute()/ExecuteAsync() выдаст исключение, и все задачи команд останутся в состоянии «ожидание активации».

Подводя итог, командные задачи следует проверять только в том случае, если Execute()/ExecuteAsync() вернули true: каждая задача будет содержать либо результат, либо ошибку (см. свойство Exception).

person andreycha    schedule 12.02.2018

  1. «Redis Cluster реализует все команды с одним ключом, доступные в нераспределенной версии Redis. Команды, выполняющие сложные операции с несколькими ключами, такие как объединения или пересечения типа Set, реализуются, а также до тех пор, пока все ключи принадлежат одному и тому же узлу». https://redis.io/topics/cluster-spec

Вы не можете отправлять операции с несколькими ключами с ключами с несколькими кластерами.

  1. "Во время транзакции можно столкнуться с двумя типами командных ошибок:

Команду может не поставить в очередь, поэтому перед вызовом EXEC может возникнуть ошибка. Например, команда может быть синтаксически неправильной (неправильное количество аргументов, неправильное имя команды, ...), или может быть какое-то критическое состояние, такое как состояние нехватки памяти (если сервер настроен на ограничение памяти с помощью параметра maxmemory). директива).

Команда может завершиться ошибкой после вызова EXEC, например, из-за того, что мы выполнили операцию над ключом с неправильным значением (например, вызов операции списка над строковым значением)». https://redis.io/topics/transactions

  1. В .Net, когда вы запускаете задачу, если внутри возникает необработанное исключение - оно не будет всплывать за пределы задачи, если вы не используете taskInstance.Wait() - тогда вы получите AggregateException и вам нужно будет проверить InnerExceptions для фактических исключений.
person Royi Mindel    schedule 12.02.2018
comment
Спасибо за Ваш ответ. К сожалению, № 2 и № 3 на самом деле не отвечают, потому что API транзакций в StackExchange.Redis добавляет дополнительную логику к чистому сценарию MULTI, постановки в очередь и EXEC. Смотрите ссылку, которую я добавил к вопросу. (Кстати, я не минусовал.) - person andreycha; 12.02.2018
comment
Что касается № 1, вы, скорее всего, правы. Хотя спецификация кластера ничего не говорит о транзакциях, я полагаю, что в среде кластера блок MULTI/EXEC можно рассматривать как команду с несколькими ключами. - person andreycha; 12.02.2018
comment
№ 1 из моего опыта использования кластера со StackExchange.Redis — действия с несколькими ключами не выполняются, когда ключи находятся в разных узлах, № 2 № 3 — я сомневаюсь, что StackExchange.Redis повторно реализует базовые функции Redis, но я проверю это. - person Royi Mindel; 12.02.2018
comment
Как я понял, кажется, что StackExchange.Redis также предоставляет базовую оболочку для сервера Redis с транзакциями, сервер Redis ставит команды в очередь до тех пор, пока не будет вызван Execute - я не думаю, что StackExchange.Redis в любом случае управляет им. - кроме как вернуть правильный ответ после выполнения. github.com/StackExchange/StackExchange.Redis/blob/master/ документы/ - person Royi Mindel; 12.02.2018