1、redis事务的特性
1.1、Redis 事务的 ACID 原则
ACID 原则我相信各位已经滚瓜烂熟了,它指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)(摘自百度百科)
对于 Redis 事务的 ACID 原则,我先说结论:Redis 的事务满足一致性和隔离性,但是原子性和持久性就不支持了。下面详细分析。
1.2、原子性
原子性定义如下(摘自百度百科):
整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
注意三个关键:要么全部完成、要么全部不完成、失败回滚
Redis 单个命令的执行是具有原子性的,但是对于事务而言,由于 Redis 放弃了事务的回滚机制,在整个事务执行阶段,如果没有碰到中断的情况(上面提到的三种情况),Redis 会继续执行下去。所以 Redis 是不具备原子性的。
至于 Redis 为什么放弃回滚机制,官网也给出了答案:
Redis 操作失败的原因只可能是语法错误或者错误的数据库类型操作,这些都是在开发层面能发现的问题不会进入到生产环境,因此不需要回滚。
Redis 内部设计推崇简单和高性能,因此不需要回滚能力。
在事务执行过程中即使发生了错误,Redis 服务也不会放弃事务的执行,它会继续执行下去,同时也不会因为已执行的错误命令而影响后续命令的执行。如下:
1.3、一致性
Redis事务是具有一致性的,这一点毋庸置疑的,下面看一下它是如何保证的。
如果一个事务在入队命令的过程中,出现了命令不存在,或者命令的格式不正确等情况,那么Redis将拒绝执行这个事务
因为在事务执行的过程中,出错的命令会被服务器识别出来,并进行相应的错误处理,所以这些出错命令不会对数据库做任何修改,也不会对事务的一致性产生任何影响。
如果服务器停机,Redis会通过RDB或者AOF这些持久化手段来恢复数据,那么数据总是保持一致的。
1.4、隔离性
隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作
通俗点将就是多个事务并发执行互不干扰。由于 Redis 使用的单线程方式来执行事务的且可以保证在整个事务执行期间不会中断去执行其他命令,所以 Redis 的事务总是可以保证隔离性的。
1.5、持久性
在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
如果 Redis 采用内存模式,因为数据不会持久化,所以持久化无法保证
如果 Redis 采用 RDB 模式,服务器只会在特定的条件才会触发,如果 Redis 执行事务后,没有触发 bgsave 操作,则无法保证持久化
如果 Redis 采用 AOF 模式,则分为以下三种情况
如果选择的是 always,则会同步调用不同操作,将命令数据写入到硬盘中,所以具有持久性
如果现在的是 everysec 或者 no,则依然需要在特定条件下触发,否则无法命令数据可以刷入硬盘,所以不具有持久性