如何在 Spring Data Redis Reactive 中使用事务?

Joh*_*han 2 java spring redis lettuce spring-data-redis

我正在尝试使用ReactiveRedisOperationsspring-data-redis 2.1.8 来执行事务,例如:

WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
Run Code Online (Sandbox Code Playgroud)

但是在浏览文档ReactiveRedisOperations. 这在反应式客户端中不可用,或者您如何实现这一点?

mp9*_*1de 5

TL;DR:使用 Reactive API 没有对 Redis 事务的适当支持

原因在于执行模型:Redis 如何执行事务以及响应式 API 应该如何工作。

使用事务时,连接进入事务状态,然后命令排队并最终执行EXEC。使用 exec 执行排队的命令会使单个命令的执行以命令为条件EXEC

考虑以下片段(生菜代码):

RedisReactiveCommands<String, String> commands = …;

commands.multi().then(commands.set("key", "value")).then(commands.exec());
Run Code Online (Sandbox Code Playgroud)

此序列以某种线性方式显示命令调用:

  • 问题 MULTI
  • 一旦MULTI完成,发出SET命令
  • 一旦SET完成,通话EXEC

需要注意的是SETSET仅在调用后完成EXEC。所以这意味着我们有一个对 exec 命令的前向引用。我们无法监听将来要执行的命令。

您可以应用解决方法:

RedisReactiveCommands<String, String> commands = …

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

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

            return commands.exec();
        });
Run Code Online (Sandbox Code Playgroud)

解决方法将在您的代码中加入命令订阅(注意:这是反应式编程中的反模式)。调用后exec(),您将获得TransactionResult回报。

另请注意:虽然您可以通过 检索结果Mono<TransactionResult>,但实际SET命令也会发出其结果(请参阅 参考资料doOnNext(…))。

话虽如此,它让我们回到实际问题:因为这些概念不能很好地协同工作,所以 Spring Data Redis 中没有用于事务使用的 API。