Как использовать транзакции в Spring Data Redis Reactive? - PullRequest
1 голос
/ 18 июня 2019

Я пытаюсь использовать ReactiveRedisOperations из spring-data-redis 2.1.8 для выполнения транзакций, например:

WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC

Но я не могу найти способ сделать это при просмотре документы или ReactiveRedisOperations.Это недоступно в реактивном клиенте, или как этого достичь?

1 Ответ

3 голосов
/ 18 июня 2019

TL; DR: отсутствует надлежащая поддержка транзакций Redis с использованием Reactive API

Причина заключается в модели выполнения: как Redis выполняет транзакции и как должен работать реактивный API.

При использовании транзакций соединение переходит в состояние транзакции, затем команды ставятся в очередь и, наконец, выполняются с EXEC.Выполнение команд в очереди с помощью exec делает условием выполнения отдельных команд команду EXEC.

Рассмотрим следующий фрагмент (код салата):

RedisReactiveCommands<String, String> commands = …;

commands.multi().then(commands.set("key", "value")).then(commands.exec());

Эта последовательность показывает вызов команды внесколько линейный способ:

  • Выпуск MULTI
  • После завершения MULTI введите команду SET
  • После завершения SET, вызовите EXEC

Предупреждение о том, что SET: SET завершается только после вызова EXEC.Таким образом, это означает, что у нас есть прямая ссылка на команду exec.Мы не можем прослушать команду, которая будет выполнена в будущем.

Вы можете применить обходной путь:

RedisReactiveCommands<String, String> commands = …

Mono<TransactionResult> tx = commands.multi()
        .flatMap(ignore -> {

            commands.set("key", "value").doOnNext(…).subscribe();

            return commands.exec();
        });

Обходной путь будет включать подписку команд в вашем коде (Внимание: этоявляется анти-паттерном в реактивном программировании).После вызова exec() вы получите TransactionResult взамен.

Обратите внимание: хотя вы можете получить результаты с помощью Mono<TransactionResult>, фактическая команда SET также выдает свой результат (см. doOnNext(…)).

Это, как говорится, позволяет нам вернуться к актуальному вопросу: поскольку эти концепции плохо работают вместе, в Spring Data Redis отсутствует API для транзакционного использования.

...