redis 有没有ACID事务
看redis官网的介绍:
redis确实是有事务的,但是和传统的ACID是否相同呢?
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务前后数据的完整性必须保持一致。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
原子性:
将多个操作当成一个整体来执行 要么全部执行,要么一个也不执行
在redis中,事务的multi命令后的操作,都将顺序生成在一个队列中,命令不会立即执行,队列中所有的命令会等待exec命令的提交后,才会被一次性执行
可以看到key1最终结果为'b'
执行过程:
如果我们的队列中有命令执行失败了呢? 整个队列会都失败吗?
key2被设值为'a',这一步是成功的,但incr 只能对数字进行操作,而'a'为字符串,显然会出错,但是查询key2结果,发现值还是'a',并未进行回滚,说明一个命令失败,不会整个队列命令失败,也就是说,redis不能保证原子性
为什么?
mysql的回滚是因为和写binlog有关,binlog记录的每一步操作,在事务提交前就已经将事务命令和操作命令记录在了log中,而redis是等exec执行完成后才写log,并且只记录操作命令,mysql的回滚是要耗时且占用线程资源的,而redis的理念就是简单快速,只能说应用场景不同而已
一致性:
一致性是指在事务执行前后,都应是一致的,而无论事务执行成功与否
redis不是一个关系型数据库,上面就说到redis不支持回滚,也就没有mysql那种关系型数据库的原子性一致性
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做:
隔离性:
隔离性指多个事务并发执行,各个事务间不会互相影响,并且在并发状态下执行的事务与串行执行的结果应该是完全相同的
redis 是单线程的,也就意味着它总是以串行方式执行,同一时刻内不会有其他事务打断当前事务的执行。redis的事务具有隔离性
持久性:
持久性指事务还行完毕后,结果就应该被保存在持久化存储器中,就是服务宕机,也能保证数据不丢失
redis有三种存储模式:
1. 只在内存中运行、存储,不进行持久化,服务宕机后,数据全部丢失
2. RDB模式的持久化存储, 定时隔一段时间通过fork子进程进行持久化,这就导致了如果早间隔同步时间内发生宕机,那这段时间的数据将会丢失,RDB是redis默认持久化方式
3. AOF模式是以写日志的方式记录写、改、删除操作 进行持久化,redis重启后会根据日志记录从前到后执行,将数据进行恢复
所以redis是支持事务持久性的