ACID 中关于原子性的定义:
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
那么 Redis 的事务到底符不符合原子性的特征呢?官方文档对事务的描述如下:
事务可以一次执行多个命令, 并且带有以下两个重要的保证:
当使用 AOF 方式做持久化的时候, Redis 会使用单个 write(2) 命令将事务写入到磁盘中。
然而,如果 Redis 服务器因为某些原因被管理员杀死,或者遇上某种硬件故障,那么可能只有部分事务命令会被成功写入到磁盘中。
如果 Redis 在重新启动时发现 AOF 文件出了这样的问题,那么它会退出,并汇报一个错误。
使用 redis-check-aof 程序可以修复这一问题:它会移除 AOF 文件中不完整事务的信息,确保服务器可以顺利启动。
但是在另一篇文章写到 Redis 的事务不是原子性的,他强调的是 Redis 事务在执行失败的时候不会进行任何重试或回滚,因此不具备原子性。
使用事务可能会遇到以下两种错误。
示例:
- Trying 127.0.0.1...
- Connected to localhost.
- Escape character is '^]'.
- MULTI
- +OK
- SET a 3
- abc
- +QUEUED
- LPOP a
- +QUEUED
- EXEC
- *2
- +OK
- -ERR Operation against a key holding the wrong kind of value
对于 EXEC 执行之前的错误,Redis 会检查出来并返回错误自动放弃事务,但是对于在 EXEC 调用后执行失败的情况,该条语句会执行失败,但事务中的其他命令仍会执行。
因此严格来说,Redis 事务确实不具备原子性的特征。
Redis 为什么不支持回滚
如果你有使用关系式数据库的经验, 那么 “Redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。
以下是这种做法的优点:
有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 INCR , 回滚是没有办法处理这些情况的。
鉴于没有任何机制能避免程序员自己造成的错误, 并且这类错误通常不会在生产环境中出现, 所以 Redis 选择了更简单、更快速的无回滚方式来处理事务。
本文是对以下参考资料的整理。
参考资料
http://redisdoc.com/topic/transaction.html
http://redisbook.readthedocs.io/en/latest/feature/transaction.html
https://zh.wikipedia.org/wiki/ACID
TOP云(zuntop.com)科技现在提供自主管理的独立服务器。除了自营香港Sonderclou...
香港服务器 具有免备案,网络覆盖面广,国内访问快,应用灵活等特点。很多人喜欢...
概述 随着互联网用户的增加,绝大部分互联网应用对并发量和响应速度都有比较高的...
【51CTO.com原创稿件】数字时代的今天,企业的生产经营离不开数据的支撑。随着5G...
香港云服务器选什么系统比较好 ?大家在租用香港云服务器时,不知道该如何挑选服...
企业该如何挑选合适的域名 ? 对于网站的域名,很多人都不知道该如何选择。要知...
2020年7月24日,新加坡首峰数据中心基金与碧桂园控股有限公司签订收购协议,在广...
1.Redis Cluster的基本概念 集群版的Redis听起来很高大上,确实相比单实例一主一...
1.我赢了所有人,却输掉了你。 2.我只是单纯的以为自己会是你生命中独特的例外...
3月16日,教育部发布《关于加强三个课堂应用的指导意见》(以下简称《意见》)。《...