请教大佬们一个关于 redis 原子性的问题

2020-03-21 16:47:14 +08:00
 ifconfig

在学习 redis,突然发现有个疑问,先引用网上的一句话:

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

假设我先在 session-1 里执行:

1 、WATCH name

2 、MULTI

3 、set name java

然后,我再去到 session-2 里执行:

1 、set name golang

再回到 session-1 里执行

4 、exec

此时,session-1 返回(nil),说明事务回滚,那不就说明事务也保持了原子性吗?

那为什么都说 redis 不具备原子性?谢谢各位大佬解答

6616 次点击
所在节点    Redis
11 条回复
Jooooooooo
2020-03-21 16:54:16 +08:00
redis 没有事务回滚的说法
labulaka521
2020-03-21 17:06:33 +08:00
这是 watch 的功能呀,如果执行 exec 时 watch 的值改变了,就不会执行了,
ifconfig
2020-03-21 17:25:15 +08:00
@labulaka521 是不是可以理解为,如果加了 watch,就没有执行,也就变相的达到了回滚的目的?
ashmodeus
2020-03-21 17:29:45 +08:00
是不是这么理解更简单一些,类似于 SQL: UPDATE tblXXX SET name = 'java' WHERE name.version = lastVersion;
huntcool001
2020-03-21 17:55:57 +08:00
Redis 的这个事物和数据库的
@ifconfig 是.

但是限制就是,redis 的 MULTI EXEC 里, 只能引用 MULTI 之前已经确定的变量, 不能在 MULTI 里读取一个数,然后根据这个数做客户端这边的判断,然后再调用下一条指令. 而数据库里的事务是可以的. 所以我们说 Redis 的事务是个不完全的. 你如果想做成在事务中根据读出来的 Redis 里的某条数据再决定调用某个命令,就要写 lua 脚本了.(lua 脚本在 redis 服务端执行)

参考:
https://redis.io/topics/transactions
https://redislabs.com/ebook/part-3-next-steps/chapter-11-scripting-redis-with-lua/11-3-doing-away-with-watchmultiexec/
https://stackoverflow.com/questions/10750626/transactions-and-watch-statement-in-redis/10751198
huntcool001
2020-03-21 17:56:55 +08:00
*修订上一条, Redis 里的事务和关系型数据库里的不太一样.
ifconfig
2020-03-21 17:58:07 +08:00
@huntcool001 非常感谢,明白
RedisMasterNode
2020-03-21 18:00:07 +08:00
所以其实正确来说,不应该讲 MULTI 解释为事务,正确的认识是使用 MULTI 使得多个命令可以串行执行不被打断,至于从准备到开始执行过程中是否有变更使用 WATCH 来检查,一旦开始执行就会全部执行完毕不被打扰
huntcool001
2020-03-21 18:07:16 +08:00
redis 的命令是具备原子性的.只是 redis 的事务不是完整的.

另外, WATCH 其他比较常见的用法, 可以 WATCH 好几个 key, 任意一个有变化,紧接着的 MULTI....EXEC 就不会被执行. 还有就是,如果 WATCH 的 key 是自己 expire(过期了),后面的 MULTI .. EXEC 是不会回滚的.
ifconfig
2020-03-21 18:11:21 +08:00
@RedisMasterNode 真大佬,膜拜
az467
2020-03-21 21:45:12 +08:00
返回 nil 只是说明 redis 根本没有执行此事务(命令队列)。
按照官网的说法,redis 事务中的命令要么都被执行,要么都不被执行,所以它是有原子性的。

什么?你说语法错误?语法出错了那不就是乱码吗?乱码又不是命令,无所谓执行不执行。
不支持复杂操作?那跟原子性有关系么?
没有自动回滚就不能拥有原子性,我 redis 并不认同(

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/654884

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX