ACID对原子性的定义:原子性:事务中的所有操作要么完成要么未完成,不会在中间环节结束。如果事务执行过程中出现错误,将恢复(Rollback)到事务开始前的状态,就好像事务从未执行过一样。那么,Redis的事务是否符合原子性的特点呢?官方文档是这样描述事务的:一个事务可以同时执行多个命令,有以下两个重要保证:一个事务是一个单独的隔离操作:在一个事务中的所有命令都会被序列化,顺序执行。交易执行过程中,不会被其他客户端发送的命令请求打断。一个事务是一个原子操作:要么执行事务中的所有命令,要么不执行任何命令。EXEC命令负责触发并执行事务中的所有命令:如果客户端使用MULTI打开一个事务后因为断线导致无法执行EXEC,则该事务中的所有命令都不会被执行。另一方面,如果客户端在开启事务后成功执行了EXEC,那么事务中的所有命令都会被执行。当使用AOF进行持久化时,Redis将使用单个write(2)命令将事务写入磁盘。但是,如果Redis服务器由于某种原因被管理员杀死,或者遇到某种硬件故障,那么只有部分事务命令可以成功写入磁盘。如果Redis在重启时发现AOF文件有这样的问题,就会报错退出。使用redis-check-aof程序来解决这个问题:它会删除AOF文件中有关未完成事务的信息,确保服务器可以正常启动。但在另一篇文章中,他写道Redis事务不是原子的。他强调Redis事务在执行失败时不会进行任何重试或回滚,因此它们不是原子的。使用事务时可能会遇到以下两类错误。在EXEC之前由事务排队的命令可能会被错误执行。例如,命令可能会产生语法错误(错误的参数数量、错误的参数名称等),或其他更严重的错误,如内存不足(如果服务器使用maxmemory设置最大内存限制)。命令可能在EXEC调用后失败。例如,事务中的命令可能会处理错误类型的键,例如在字符串键上使用列表命令,等等。例子:Trying127.0.0.1...Connectedtolocalhost.Escapecharacteris'^]'.MULTI+OKSETa3abc+QUEUEDLPOPa+QUEUEDEXEC*2+OK-ERROperationagainstakeyholdingthewrongkindofvalue对于EXEC执行前的错误,Redis会检查出来并返回错误自动放弃事务,但是如果EXEC调用后执行失败,则语句执行失败,但事务中的其他命令仍会执行。所以严格来说,Redis事务不具备原子性的特点。为什么Redis不支持回滚如果你有使用关系型数据库的经验,那么“Redis在事务失败时不回滚,而是继续执行剩下的命令”可能会让你觉得有些陌生。以下是这种方法的优点:Redis命令只会因语法不正确(并且这些问题无法在入队时检测到),或者在错误类型的键上使用的命令而失败:这就是说,从实用性的角度来看看来,失败的命令是由编程错误引起的,这些错误应该在开发过程中发现,而不应该出现在生产环境中。由于不需要支持回滚,Redis的内部结构可以保持简单和快速。有一种观点认为Redis处理事务的方式会导致bug。但需要注意的是,一般情况下,回滚并不能解决编程错误导致的问题。比如你想用INCR命令给一个key的值加1,结果不小心加了2,或者对错误类型的key进行了INCR,rollback就没有办法处理这些情况。由于没有机制避免程序员自己造成的错误,而这种错误通常不会出现在生产环境中,因此Redis选择了一种更简单、更快速的方式来处理事务而无需回滚。本文是以下参考资料的汇编。参考资料http://redisdoc.com/topic/transaction.htmlhttp://redisbook.readthedocs.io/en/latest/feature/transaction.htmlhttps://zh.wikipedia.org/wiki/ACID
