我正在尝试使用spring-data-redis 2.1.8中的ReactiveRedisOperations
进行交易,例如:
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
但是在浏览docs或ReactiveRedisOperations
时,我似乎找不到解决方法。这在反应式客户端中不可用,或者您如何实现呢?
答案 0 :(得分:3)
原因在于执行模型: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
警告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。