ACID 中关于原子性的定义:

原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

那么 Redis 的事务到底符不符合原子性的特征呢?官方文档对事务的描述如下:

事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
  • EXEC 命令负责触发并执行事务中的所有命令:如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行。
  • 另一方面,如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。

当使用 AOF 方式做持久化的时候, Redis 会使用单个 write(2) 命令将事务写入到磁盘中。

然而,如果 Redis 服务器因为某些原因被管理员杀死,或者遇上某种硬件故障,那么可能只有部分事务命令会被成功写入到磁盘中。

如果 Redis 在重新启动时发现 AOF 文件出了这样的问题,那么它会退出,并汇报一个错误。

使用 redis-check-aof 程序可以修复这一问题:它会移除 AOF 文件中不完整事务的信息,确保服务器可以顺利启动。

但是在另一篇文章写到 Redis 的事务不是原子性的,他强调的是 Redis 事务在执行失败的时候不会进行任何重试或回滚,因此不具备原子性。

使用事务可能会遇到以下两种错误。

  • 事务在执行 EXEC 之前,入队的命令可能会出错。比如说,命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)。
  • 命令可能在 EXEC 调用之后失败。举个例子,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。

示例:

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 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 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

Redis 的事务到底是不是原子性的的更多相关文章

  1. redis的事务不是原子性

    Reference: https://blog.csdn.net/u011692780/article/details/81213010 一.事务的四大特性 关系型数据库的事务具有四个特性: 1. 原 ...

  2. Redis的事务不是原子性的

    1.事务的四大特性 原子性(Atomicity):化学中的原子指不可再分的基本微粒,数据库中原子性强调事务是一个不可分割的整体,事务开始后所有操作要么全部成功,要么全部失败,不可能停滞在中间某个环节. ...

  3. 12、Redis的事务

    写在前面的话:读书破万卷,编码如有神 --------------------------------------------------------------------------------- ...

  4. redis: 事务管理(九)

    redis的事务 不保证原子性 三个步骤:开启事务.命令入队.执行事务 开启事务:multi 执行事务:exec 127.0.0.1:6379> multi #开启事务 OK 127.0.0.1 ...

  5. 【高频 Redis 面试题】Redis 事务是否具备原子性?

    一.Redis 事务的实现原理 一个事务从开始到结束通常会经历以下三个阶段: 1.事务开始 客户端发送 MULTI 命令,服务器执行 MULTI 命令逻辑. 服务器会在客户端状态(redisClien ...

  6. 面试官:Redis的事务满足原子性吗?

    原创:码农参上(微信公众号ID:CODER_SANJYOU),欢迎分享,转载请保留出处. 谈起数据库的事务来,估计很多同学的第一反应都是ACID,而排在ACID中首位的A原子性,要求一个事务中的所有操 ...

  7. Redis的事务

    Redis对事务的支持是部分支持,不想oracle,要么都成功要么都失败,Redis可以部分成功部分失败 1 是什么: 可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺 ...

  8. Redis笔记(五)Redis的事务

    >>关系型数据库的事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. Atomic(原子性): 一个事务(transaction)中的 ...

  9. Redis的事务功能详解

    Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础.Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >Re ...

随机推荐

  1. Cursor for loop in Oracle

    declare l_sql ); -- variable that contains a query l_c sys_refcursor; -- cursor variable(weak cursor ...

  2. angular笔记_4(函数)

    angular.isString();是否字符串 angular.isNumber();是否数字 angular.isArray();是否数组 angular.isDate();是否日期/时间 ang ...

  3. Fenng早年间对推荐系统的思考

    http://mt.dbanotes.net/review/bi_story.html

  4. Centos6.5部署Rsyslog+cron+rsync备份服务器

    1.前言 rsync是一种快速且功能非常广泛的文件复制工具.它可以在本地复制,通过任何远程shell复制到/从另一个主机复制,也可以复制到/从远程rsync守护进程.它提供了大量的选项,可以控制其行为 ...

  5. Java笔记(六)列表和队列

    列表和队列 一)ArrayList 1.基本原理 ArrayList是一个泛型容器.内部会有一个数组elementData,一般会有预留空间 有一个整数记录实际的元素个数. private trans ...

  6. python基础一 ------可迭代类型的连接

    对可迭代迭代进行连接,返回一个可迭代对象 两种方式: 并行连接 zip() 串行连接 itertools.chain from itertools import chain #并行连接 print(& ...

  7. java中打开文件流后要关闭后重新打开

    记录错误,打开文件流一定要关闭并重新打开文件流,不然取的文件内容永远是第一次取的文件内容: /** * 读取配置文件 */ private Properties readProperties() { ...

  8. js点击回到顶部

    ---恢复内容开始--- <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  9. 解决 插件LArea 在IOS上浮出软键盘问题

    移动端使用 省市县城市选择三级联动的时候, 插件LArea 会有一个问题 ios浏览器和ie9已下(包括ie9)浏览器都有input设置readonly之后input还有聚焦的问题. ios inpu ...

  10. BZOJ4167 : 永远的竹笋采摘

    首先枚举出所有可能成为区间最小差值的点对$(j,i)$. 枚举每个位置作为右端点$i$,假设$a[j]>a[i]$. 找到第一个这样的$j$,那么可以将下一个$a[j]$的范围缩小到$(a[i] ...