Я пытаюсь использовать ReactiveRedisOperations из spring-data-redis 2.1.8 для выполнения транзакций, например:
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
Но я не могу найти способ сделать это при просмотре документы или ReactiveRedisOperations. Это недоступно в реактивном клиенте или как вы можете этого добиться?




Причина кроется в модели выполнения: как Redis выполняет транзакции и как должен работать реактивный API.
При использовании транзакций соединение переходит в транзакционное состояние, затем команды ставятся в очередь и, наконец, выполняются с помощью EXEC. Выполнение команд в очереди с помощью exec делает выполнение отдельных команд зависимым от команды EXEC.
Рассмотрим следующий фрагмент (код салата):
RedisReactiveCommands<String, String> commands = …;
commands.multi().then(commands.set("key", "value")).then(commands.exec());
Эта последовательность показывает вызов команды несколько линейным образом:
MULTIMULTI введите команду SETSET завершится, звоните 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 для транзакционного использования.
Нельзя ли решить антипаттерн «плавающая подписка», просто используя
Mono.when?var command = commands.set("key", "value").doOnNext(…), а затемreturn Mono.when(commands.exec(), command)? И с учетом сказанного я не могу найтиmultiкак метод в Spring Boot 2.4.1, он был удален?