• 【Redis】深入理解 Redis 事务机制



    前言

    一、回顾 MySQL 事务

    1.1 MySQL 事务的概念与特性

    MySQL事务是一种用于管理数据库操作的机制,它确保一组相关的 SQL 操作要么全部成功执行,要么全部失败,从而维护数据的一致性和完整性。事务是数据库管理系统中的核心概念之一,它通常遵循 ACID 属性:

    1. 原子性(Atomicity): 事务是一个原子操作,要么全部执行成功,要么全部失败。如果其中任何一部分操作失败,整个事务将被回滚,数据库状态将保持不变。

    2. 一致性(Consistency): 事务的执行将数据库从一个一致的状态转移到另一个一致的状态。这意味着事务执行后,数据库必须满足事先定义的完整性约束。

    3. 隔离性(Isolation): 隔离性定义了多个并发事务之间的相互影响程度。不同的隔离级别提供不同的隔离程度,包括读未提交、读已提交、可重复读和串行化等级。

    4. 持久性(Durability): 一旦事务被提交,其结果将永久存储在数据库中,并在系统故障后保持不变。

    1.1 MySQL 事务的管理

    在MySQL中,可以使用以下关键字来管理事务:

    • BEGIN:开始一个新的事务。
    • COMMIT:提交事务,将更改保存到数据库。
    • ROLLBACK:回滚事务,撤销未提交的更改。
    • SAVEPOINT:创建一个保存点,可以在事务中的特定位置回滚。
    • SET TRANSACTION:设置事务的属性,如隔离级别。

    以下是一个简单的MySQL事务示例:

    BEGIN;  -- 开始事务
    
    -- 在事务中执行一些SQL操作
    INSERT INTO users (id, username) VALUES (1, 'user1');
    UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
    
    -- 如果一切正常,提交事务
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如果在事务执行期间发生错误或者需要取消事务,可以使用ROLLBACK命令来回滚事务,这将撤销所有在事务中的更改。

    BEGIN;  -- 开始事务
    
    -- 在事务中执行一些SQL操作
    INSERT INTO users (id, username) VALUES (2, 'user2');
    -- 发生错误,回滚事务
    ROLLBACK;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用事务可以确保数据库的数据完整性,特别是在多个用户同时访问数据库时。根据具体的应用场景和需求,可以选择不同的隔离级别,以平衡并发性和一致性之间的需求。在实际应用中,正确使用事务是确保数据的一致性和可靠性的关键。

    二、对 Redis 事务的认识

    2.1 什么是 Redis 的事务

    2.1.1 Redis 事务的概念

    简单来说,Redis事务 允许将一组 Redis 命令组合成一个单独的、不可中断的操作序列。这意味着,一旦开始了一个 Redis 事务,任何在事务执行期间的其他客户端的命令都不会中断这个事务,而是会排队等待执行,直到事务被提交或取消执行。

    2.1.2 对 Redis 事务的深入理解

    • Redis 事务的核心概念涉及在 Redis 服务器上创建一个称为 "事务队列" 的缓冲区。当开启一个事务后,所有与该事务相关的命令都将按顺序排队进入该队列。只有当发送执行事务的命令时,队列中的命令才会以原子的方式依次执行,这确保了这组命令要么全部成功,要么全部失败。

    • 在事务队列中,可以包括任意数量的 Redis 命令,包括读取和写入操作,以便进行一系列复杂的操作。然而,需要注意的是,Redis 事务并不支持像传统数据库那样的隔离级别和回滚机制。因此,应用程序需要自行处理错误和回滚逻辑。

    • 未收到执行命令的事务在 Redis 服务器中处于排队等待状态,虽然将命令发送给了服务器,但并没有执行,同时也不会影响其他客户端命令的正常执行。

    总之,Redis 事务为提供了一种 将多个命令打包成一个原子操作的能力 ,这在需要 确保一系列操作的一致性时 非常有用。然而,它与传统数据库的事务有一些区别,特别是在隔离性和持久性方面。

    2.2 Redis 事务与 MySQL 事务的比较

    虽然 Redis 和 MySQL 都涉及事务的概念,但在实现和应用方面存在一些关键差异。

    2.2.1 事务的粒度

    Redis事务: Redis 事务通常以单个命令的粒度工作。多个 Redis 命令可以放入一个事务中,但每个命令本身是不可分割的。这允许执行一系列简单的操作,但不能跨多个 Redis 命令执行复杂的事务。

    MySQL事务: MySQL 事务具有更广泛的粒度,允许跨多个 SQ L语句执行复杂的事务,包括事务的开始和结束。

    2.2.2 ACID 属性

    Redis事务: Redis 事务支持原子性(Atomicity)和一致性(Consistency),确保一组命令要么全部成功,要么全部失败,并在事务执行后维护数据的一致性。但 Redis 不支持传统数据库中的隔离性(Isolation)和持久性(Durability)。

    MySQL事务: MySQL 事务支持完整的 ACID 属性,包括原子性、一致性、隔离性和持久性。这使得 MySQL 事务在需要严格事务完整性的应用中非常有用,如金融和电子商务系统。

    2.2.3 并发控制

    Redis事务: Redis 事务是单线程的,一次只能执行一个事务。这限制了并发性,因为其他客户端的命令必须排队等待执行。同时 Redis 使用乐观锁定来控制并发。

    MySQL事务: MySQL 具有强大的并发控制机制,支持多个事务同时执行,可以根据需要选择不同的隔离级别,从而平衡并发性和一致性。

    2.2.4 错误处理和回滚

    Redis事务: Redis 事务提供了回滚操作的能力,可以使用 DISCARD 命令来取消当前事务并清除已排队的命令。但 Redis 不会自动回滚事务中的错误命令。

    MySQL事务: MySQL事务支持显式的回滚操作,可以使用 ROLLBACK 来撤销已执行的事务中的命令,并恢复到事务开始之前的状态。

    2.2.5 应用场景

    Redis事务: Redis 事务通常用于缓存、队列、计数器等特定用例,其中需要简单的原子操作,但不强调严格的隔离性和持久性

    MySQL事务: MySQL 事务广泛用于支持事务完整性的应用程序,如电子商务、金融系统等,这些应用需要强大的 ACID 支持。

    总之,Redis事务和MySQL事务在粒度、ACID属性、并发控制、错误处理和应用场景等方面存在重要差异。选择使用哪种类型的事务取决于项目需求和性能要求。在某些情况下,Redis和MySQL可以共同使用,以满足不同类型的事务需求。

    三、Redis 事务相关命令

    Redis 事务是一种强大的功能,允许我们将一系列 Redis 命令打包在一起,以确保它们要么全部成功执行,要么全部失败。在 Redis 中,有一些关键的命令用于处理事务,包括 MULTIEXECDISCARDWATCHUNWATCH。下面将详细介绍这些命令的作用和用法。

    3.1 MULTI

    MULTI 命令用于开启一个事务。在执行 MULTI 命令后,Redis 会进入事务模式,接下来的命令都会被加入到事务队列中等待执行。如果执行成功,MULTI 命令会返回 “OK”。

    实例:

    127.0.0.1:6379> MULTI
    OK
    
    • 1
    • 2

    3.2 EXEC

    EXEC 命令用于执行事务中的命令队列。在执行 EXEC 命令时,Redis 会按照事务队列中命令的顺序,以原子的方式依次执行这些命令。如果事务中的所有命令都执行成功,EXEC 命令返回一个包含每个命令执行结果的数组;如果有命令执行失败,事务中的所有命令都会被取消。

    实例:

    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> SET k1 1
    QUEUED
    127.0.0.1:6379> SET k2 2
    QUEUED
    127.0.0.1:6379> SET k3 3
    QUEUED
    127.0.0.1:6379> EXEC
    1) OK
    2) OK
    3) OK
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.3 DISCARD

    DISCARD 命令用于放弃当前事务。执行 DISCARD 命令会清空事务队列中的所有命令,之前的操作都不会被真正执行。

    实例:

    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> SET k1 1
    QUEUED
    127.0.0.1:6379> SET k2 2
    QUEUED
    127.0.0.1:6379> DISCARD
    OK
    127.0.0.1:6379> GET k1
    (nil)
    127.0.0.1:6379> GET k2
    (nil)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.4 WATCH

    在执行事务时,如果某个事务中的键被其他客户端修改,可能会导致数据不一致的问题。WATCH 命令用于解决这个问题,它可以监控一组指定的键,如果这些键在事务执行前被其他客户端修改,事务将被取消。

    实例:

    # 客户端1 开始监控 k1
    127.0.0.1:6379> WATCH k1
    OK
    
    # 客户端2 修改 k1
    127.0.0.1:6379> SET k1 100
    OK
    
    # 客户端1 执行事务,但由于 k1 被修改,事务将被取消
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> SET k1 200
    QUEUED
    127.0.0.1:6379> EXEC
    (nil)
    # 获取 k1 的值
    127.0.0.1:6379> GET k1
    "100"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    WATCH原理:

    WATCH 的原理可以简单概括为以下几个步骤:

    1. 客户端执行 WATCH 命令并指定要监视的键。
    2. Redis 在服务器端创建一个监视器(Watcher)来监视这些键。监视器会记录被监视键的当前状态,通常是版本号或时间戳
    3. 客户端进入事务模式,可以执行多个命令,但这些命令不会立即执行,而是进入一个队列中等待。
    4. 在执行事务之前,客户端要求服务器检查监视器中被监视键的状态是否发生变化。这是通过比较监视器中的状态与当前键的状态来完成的。
    5. 如果监视器发现被监视键的状态在执行事务之前已经发生变化,它会通知客户端取消事务。这是乐观锁的核心思想:如果其他客户端在执行 WATCHEXEC 之间修改了被监视的键,那么事务将失败。
    6. 如果监视器未发现变化,客户端可以执行事务中的命令,这些命令会按顺序执行。

    总之,WATCH 的原理是通过在服务器端创建监视器来监控一组键的状态,并在执行事务前检查这些键的状态是否发生变化。如果有其他客户端修改了被监视键,事务将被取消,以确保数据的一致性。这使得 Redis 能够在并发环境中实现事务操作,而不会引发竞态条件等问题。

    3.5 UNWATCH

    UNWATCH 命令用于取消对键的监控,是 WATCH 命令的逆操作。如果你不再需要监控某些键,可以使用 UNWATCH 来取消监控。

    127.0.0.1:6379> set key 1
    OK
    127.0.0.1:6379> WATCH key
    OK
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> set key 2
    QUEUED
    127.0.0.1:6379> set key 3
    QUEUED
    127.0.0.1:6379> DISCARD
    OK
    127.0.0.1:6379> UNWATCH
    OK
    127.0.0.1:6379> 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    以上就是 Redis 事务相关命令的详细介绍。通过合理使用这些命令,就可以构建出安全、可靠的事务操作,确保数据的一致性和完整性。当然,在使用事务时,需要根据具体的业务需求和情况来决定是否使用监控命令 WATCH

    四、总结

    在本文中,深入探讨了Redis事务的概念和相关命令,以及 Redis 事务与 MySQL 事务的比较。以下是本文的主要要点总结:

    1. Redis 事务的核心概念: Redis 事务允许将多个 Redis 命令打包成一个单一、不可中断的操作序列。这确保了这些命令要么全部成功执行,要么全部失败。

    2. Redis 事务相关命令: Redis 提供了一组关键命令来管理事务,包括MULTI(开始事务)、EXEC(提交事务)、DISCARD(取消事务)、WATCH(监视键变化)、和UNWATCH(取消监视)。

    3. Redis 事务与 MySQL 事务的比较: Redis 事务与 MySQL 事务在事务粒度、ACID 属性、并发控制、错误处理和应用场景等方面存在不同。Redis 事务通常用于简单的原子操作,而 MySQL 事务支持更广泛的 ACID 属性,适用于需要强大事务完整性的应用。

    4. Redis 事务的限制: Redis 事务不支持传统数据库中的隔离级别和持久性,需要应用程序自行处理错误和回滚逻辑。

    在选择使用 Redis 事务还是 MySQL 事务时,应根据项目需求和性能要求权衡不同的特性和限制。了解 Redis 事务的工作原理和使用方式,可以帮助我们更好地利用 Redis 的事务功能。

  • 相关阅读:
    你认为低代码能够完全取代程序猿吗?
    C++----unordered_map unordered_set使用及模拟
    Redis订阅和发布
    MFC 发起 HTTP Post 请求 发送MES消息
    初识 C语言文件操作
    鸿翼归档:释放企业存储压力 提升数据利用效率
    设计模式 18 中介者模式
    vue组件间传值之插槽
    水波纹文字效果动画
    Mac 安装nvm
  • 原文地址:https://blog.csdn.net/qq_61635026/article/details/132915120