什么是ACID
第一个是原子性:事务中的多个操作必须都完成,或者都不完成
第二个是一致性:数据库中的数据在事务执行前后是一致的,例如转账业务中,无论事务是否成功,转账者和收款 人的总额应该是不变的;
第三个是隔离性:数据库在执行一个事务的时候,其他操作无法存取正在执行事务访问的数据
第四个是持久性:数据库执行事务后,数据的修改要被持久化保存下来。
Redis如何实现事务
redis用MULTI、EXEC两个命令来完成。
第一步,客户端使用multl开启事务
第二步,客户端发送命令到服务器端,这些操作就是redis本身提供的数据读写命令,这些命令虽然被传到服务器端但是不会真的被执行,而是会暂存到一个命令队列里面。
第三步,客户端发送EXEC,服务端真正执行事务
Redis的事务机制能保证哪些属性
原子性
命令入队时就报错,会放弃事务执行,保证原子性
命令入队时未检测出来,实际执行时会报错,不能保证原子性
EXEC命令执行时,redis实例故障,如果开启了AOF日志,可以保证原子性
一致性
情况1:命令入队时报错
事务会被放弃执行,可以保证一致性
情况2:命令执行时报错
错误命令不会被执行,正确命令会被执行,可以保证一致性
情况3:EXEC命令时redis实例宕机
如果没有开启AOF和RDB,那么宕机后,数据就没有了,可以保证一致性
如果开启了RDB,事务执行时是不会进行RDB快照的,所以事务命令不会保存到RDB中,可以保证一致性
如果使用了AOF,而事务操作还没有被记录到 AOF 日志时,实例就发生了故障,那么,使用 AOF 日志恢复的数据库数据是一致的。如果只有部分操作被记录到了 AOF 日志,我们可以使用 redis-check-aof 清除事务中已经完成的操作,数据库恢复后也是一致的。
隔离性
分为在EXEC执行前和执行后
执行前:需要用WATCH机制来保障,
执行后:可以保证
WATCH机制:在事务执行前,监控一个或多个键的值变化情况,当事务调用EXEC命令执行时,WATCH机制会检查监控的键是否被其他客户端修改,如果被修改了,则放弃事务的执行来保障隔离性。
持久性
如果 Redis 没有使用 RDB 或 AOF,那么事务的持久化属性肯定得不到保证。
如果 Redis 使用了 RDB 模式,那么,在一个事务执行后,而下一次的 RDB 快照还未执行前,如果发生了实例宕机,这种情况下,事务修改的数据也是不能保证持久化的。
如果 Redis 采用了 AOF 模式,因为 AOF 模式的三种配置选项 no、everysec 和 always 都会存在数据丢失的情况,所以,事务的持久性属性也还是得不到保证。
所以,不管 Redis 采用什么持久化模式,事务的持久性属性是得不到保证的。