31 | 事务机制:Redis能实现ACID属性吗?

极客时间 | 《Redis核心技术与实战》学习笔记目录

原文

事务在执行时,会提供专门的属性保证,包括

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

Redis 如何实现事务?

事务的执行过程包含三个步骤,Redis 提供了 MULTI、EXEC 两个命令来完成这三个步骤

  • 第一步,客户端要使用一个命令显式地表示一个事务的开启:MULTI 命令
  • 第二步,客户端把事务中本身要执行的具体操作(例如增删改数据)发送给服务器端。这些操作就是 Redis 本身提供的数据读写命令,例如 GET、SET 等。不过,这些命令虽然被客户端发送到了服务器端,但 Redis 实例只是把这些命令暂存到一个命令队列中,并不会立即执行。
  • 第三步,客户端向服务器端发送提交事务的命令,让数据库实际执行第二步中发送的具体操作。Redis 提供的 EXEC 命令就是执行事务提交的。当服务器端收到 EXEC 命令后,才会实际执行命令队列中的所有命令。

Redis 的事务机制能保证哪些属性?

原子性

Redis 中并没有提供回滚机制

只有当事务中使用的命令语法有误时,原子性得不到保证,在其它情况下,事务都可以原子性执行

  • DISCARD 命令:只能用来主动放弃事务执行,把暂存的命令队列清空,起不到回滚的效果
  • MULTI 和 EXEC 配合使用不能保证原子性
    • 队列中的命令,因类型不匹配导致失败,仅当前命令执行失败,不影响其他命令执行

举例

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

一致性

隔离性

WATCH 机制的作用是,在事务执行前,监控一个或多个键的值变化情况,当事务调用 EXEC 命令执行时,WATCH 机制会先检查监控的键是否被其它客户端修改了。如果修改了,就放弃事务执行,避免事务的隔离性被破坏。然后,客户端可以再次执行事务,此时,如果没有并发修改事务数据的操作了,事务就能正常执行,隔离性也得到了保证。

持久性

不管 Redis 采用什么持久化模式,事务的持久性属性是得不到保证的

留言区

为什么Redis不支持回滚?

Redis 官网文档 Why Redis does not support roll backs?

  1. 只有当事务中使用的命令语法有误时,原子性得不到保证
  2. 回滚并不能避免编程错误
  3. 不支持回滚实现更简单、高效
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus