Redis事务原子性

3
我对Redis还不熟悉,在阅读官方网站上的事务处理时,有一点让我很困惑。
1. 它说:
所有命令都会被处理,或者全部不处理,因此Redis事务也是原子操作。
2. 然后又说:
即使一个命令失败了,队列中的所有其他命令也会被处理 -
这两者不是相互矛盾吗?
4个回答

4
这是关于不同的事情。Redis有管道 - 客户端可以一次发送多个命令给Redis。在管道中批处理可以是事务。当事务失败时,事务内的所有命令都将被丢弃,但是在EXEC命令之后排队的任何管道化命令都将被执行。
更多信息请参见http://redis.io/topics/pipelininghttp://redis.io/topics/transactions

2

处理过的命令和失败之间有所不同。在SQL中,如果任何一个命令失败,整个事务将被回滚,就好像没有任何命令被执行一样。在redis中,命令的失败并不会阻止其他命令的处理或已经处理的命令,每个命令都可以独立地成功或失败。

因此,如果您增加了一个计数器,然后尝试将另一个键设置为值并且失败了,增量仍然发生,并且不会被回滚。因此,即使其中一个命令失败,所有命令也都被处理了。


1
简单来说,Redis TRANSACTION 拥有事务所应具备的任何功能,但在失败时无法回滚。因为 Redis 的作者认为,在失败时回滚功能是不必要的,失败只能由编程错误引起。
也许我应该告诉你,通过 multi 系列命令实现的 Redis 事务并不是一个好选择,因为它是一种过时的功能(作者认为 Lua 是一种更好的方式,使 multi 完全不必要)。使用 Redis Lua 更好!
Redis 作者的引用:
“Redis 脚本从定义上就是事务性的,因此,您可以使用 Redis 事务所能做的一切,也可以使用脚本来完成,并且通常脚本会更简单、更快。 这种重复是由于脚本是在 Redis 2.6 中引入的,而事务已经存在很长时间了。然而,我们短时间内不太可能删除对事务的支持,因为即使不使用 Redis 脚本,仍然可以避免竞争条件,特别是由于 Redis 事务的实现复杂度很小。 然而,在不久的将来,我们可能会看到整个用户群体都在使用脚本。如果出现这种情况,我们可能会废弃并最终删除事务。”
你应该仔细查看Redis文档中的Lua章节。它确实是一个更好、更强大的解决方案,但需要你了解一些Lua知识。

如果需要更多信息,请回复。


谢谢!这个表单是否正确? return redis.call("INCR",KEYS[1]) else local i = ARGV[1]+1 redis.call("SET", KEYS[1],i) return i end``` - undefined
1
@emanuel07 如果我没记错的话,基本上是正确的。最好的方法是运行一下来确定。Redis现在提供了丰富的调试Lua脚本的方式。 - undefined

0

我认为Redis事务的“原子性”定义有点像“线性化”。

参考https://en.wikipedia.org/wiki/Linearizability

这种瞬间发生或不可分割的属性,导致使用“原子性”作为“线性化”的替代术语。

在这种情况下,Redis确保事务的执行不会被其他命令干扰(或不可分割),并且事务中的命令可以按顺序逐个执行。

关于Redis允许部分成功的原因,这应该是关于“回滚怎么办”的设计问题,而不是原子性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接