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

时间:2019-06-18 11:21:22

标签: java spring redis spring-data-redis lettuce

我正在尝试使用spring-data-redis 2.1.8中的ReactiveRedisOperations进行交易,例如:

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

但是在浏览docsReactiveRedisOperations时,我似乎找不到解决方法。这在反应式客户端中不可用,或者您如何实现呢?

1 个答案:

答案 0 :(得分:3)

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

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

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

请考虑以下代码段(Lettuce代码):

RedisReactiveCommands<String, String> commands = …;

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

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

  • 问题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();
        });

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

还请注意:尽管您可以通过Mono<TransactionResult>检索结果,但是实际的SET命令也会发出其结果(请参见doOnNext(…))。

话虽如此,它使我们可以回过头来讨论一个实际的问题:由于这些概念不能很好地协同工作,因此Spring Data Redis中没有用于事务的API。