Возникло несколько вопросов по работе транзакций в StackExchange.Redis:
Можно ли помещать в одну транзакцию команды, предназначенные для разных нод в кластере? Например, у ключа первой команды хэштэг {1}, а у ключа второй команды -- {2}. (Подозреваю, что нельзя.)
В каких случаях вызов Execute()/ExecuteAsync() возвращает false? Только когда установленные условия не были выполнены? Может ли вызов вернуть false, если условия вообще не были установлены?
Eсли происходит ошибка сети или внутренняя ошибка Redis, то вызов Execute()/ExecuteAsync() выбросит исключение или вернет false? Нужно ли еще проверять таски всех команд (предполагается, что все команды корректные и не должны выбрасывать ошибок) или они просто будут в состоянии cancelled?
К сожалению, документация насчет #2 и #3 не слишком подробная.
Этот вопрос -- дубликат с enSO
Ответ
Я заглянул в исходники StackExchange.Redis, а также поигрался с драйвером, и вот что обнаружил:
при вызове методов команд у ITransaction никакого общения с сервером не происходит
драйвер обращается к Redis только после вызова Execute()/ExecuteAsync()
Поэтому ответы следующие:
Как подсказали в оригинальном вопросе на enSO, в случае кластера все multi-key команды должны соответствовать одному слоту. В контексте кластера транзакция считается multi-key командой.
Redis Cluster implements all the single key commands available in the
non-distributed version of Redis. Commands performing complex
multi-key operations like Set type unions or intersections are
implemented as well as long as the keys all belong to the same node.
https://redis.io/topics/cluster-spec
При попытке выполнить транзакцию с невалидными ключами получим исключение "Multi-key operations must involve a single slot".
Execute()/ExecuteAsync() возвращает false в двух случаях: когда условия транзакции не были выполнены и транзакция была отменена, и когда драйвер не смог поставить команду в очередь (например, если на сервере кончилась память). Все таски при этом помечаются как canceled. Также Execute()/ExecuteAsync() не возвращает false если некоторые команды завершились неудачно (например, если команда была адресована ключу с неправильным типом значения).
В случае проблем с сетью, Execute()/ExecuteAsync() выбрасывает исключение, а все таски остаются в состоянии waiting for activation.
Итого, таски следует проверять только когда Execute()/ExecuteAsync() возвращает true: каждый таск будет содержать или результат команды, или ошибку (см. свойство Exception).
Комментариев нет:
Отправить комментарий