返回顶部

面试题之Redis是否支持事务

联想软开暑期实习 一面

一、问题

刚说了MySQL事务,说一下Redis是否支持ACID

我:balabal....
面试官:中间原子性说错了

注:以下为一些不太完整的总结。

二、Redis事务

1、事务ACID

事务是一系列严密的逻辑操作,可以使一条SQL语句也可以是一组,是恢复和并发控制的基本单元。
ACID指一致性,原子性,隔离性,持久性。
原子性:事务中的多个操作必须度完成,或者都不完成。
一致性:数据库中的数据在事务执行前后状态是一致的。
隔离性:数据库执行该事务的时候,不受其他事务影响。
持久性:事务对数据的修改持久化保存。
其中在MySQL中一致性是最终追求的目标,隔离性由锁机制实现,原子性和持久性由redolog和undolog保证。

2、Redis如何实现事务

Redis通过命令开启和提交事务,和命令队列的形式支持事务

  • MULTI开启事务。
  • 提交redis数据操作命令到命令队列中,不会立即执行。
  • EXEC提交事务,实际执行队列中的命令。

3、Redis事务机制保证哪些属性

(1)原子性:

  • 第一种情况,执行EXEC命令前,客户端发送的命令本身有错误,比如语法问题或者本身命令不存在,这些命令入队就检测出来错误。后续即使添加正确命令,执行EXEC命令提交事务也会失败。保证原子性。
  • 第二种情况,错误命令入队redis未检查出来,比如命令和操作数据不符,这是会把正确命令执行完,错误命令无法执行,因而命令队列中的所有命令只执行了一部分事务无法保证原子性。同样在命令入队之后,如果发现命令有错,提供DISCARD命令可以主动放弃事务执行清空命令队列
  • 第三种情况,执行EXEC命令,redis故障,导致执行失败。如果开启了AOF日志记录命令,就可以恢复并不执行事务操作,保持原子性,如果未开启日志,则无法保证。

也就是说:

  • 如果命令入队就报错,会放弃事务,保证原子性
  • 如果命令入队没报错,实际执行报错,不保证原子性
  • EXEC命令执行时候故障,如果开启了AOF日志,则保证原子性

(2)一致性:

  • 命令入队就报错,事务会被放弃,保持一致性
  • 执行才报错,错误的命令不执行,正确的命令执行,也保证一致性
  • 执行EXEC命令redis发生故障。如果记录了日志,可以清除事务操作,如果没记录日志,那么就可以恢复到事务执行前的状态,也是保持一致性。

(3)隔离性
分两种情况:

  • 并发操作在EXEC命令执行前,要使用WATCH机制保证隔离性,否则无法保证。
  • 并发操作在EXEC后,可以保证

WATCH机制可以再事务执行前监控一个或者多个键的值变化情况,如果执行EXEC事务,WATCH机制会检查监控的键是否被其他客户端修改了,就放弃事务,避免被破坏隔离性。

如果没有WATCH机制,可能直接开启事务的命令读取的数据,在事务未提交之前,其他事务可能就修改该数据,提交事务读取的数据不一致了。

(4)持久性
无论是什么持久化模式,由于是内存数据库,掉电宕机,都无法保证修改的数据化持久化属性。

4、总结

4个命令支持事务

redis事务机制可以保证一致性和隔离性,无法保证持久性,但是对于redis而言,本身是内存数据库,所以持久化不是必须属性。
原子性需要自己进行检查,尽可能保证。

posted on 2022-05-28 13:40  weilanhanf  阅读(1914)  评论(0编辑  收藏  举报

导航