LiSheng's blog LiSheng's blog
首页
笔记
个人简历
随笔集
GitHub (opens new window)
首页
笔记
个人简历
随笔集
GitHub (opens new window)
  • golang

  • cplus

  • leetcode

  • 存储技术

  • 分布式系统

  • 计算机网络

  • Linux操作系统

  • Redis

    • 大纲
    • redis持久化策略
    • redis事务
      • redis分布式锁
      • redis高可用
      • redis主从同步
      • Redis是什么
      • Redis基本数据结构
      • Redis为什么这么快
      • 缓存击穿、缓存穿透、缓存雪崩
      • 热Key问题,如何解决热key问题
      • Redis 过期策略和内存淘汰策略
      • Redis 的持久化机制
      • Redis的高可用
      • 使用过Redis分布式锁
      • Redis的跳跃表
      • MySQL与Redis 如何保证双写一致性
      • Redis的Hash 冲突怎么办
      • 布隆过滤器
      • Redis 事务机制
    • 其他

    • 笔记
    • Redis
    lisheng
    2024-09-10
    目录

    redis事务

    Redis 事务(Transactions)是一个一次性执行多个命令的功能。通过事务,Redis 能够保证一系列命令按顺序执行而不被其他客户端的命令打断。尽管与传统数据库中的事务概念相比,Redis 的事务功能较为简单,但在某些场景下非常有用。

    # 1. Redis事务的基本概念

    Redis 中的事务由以下几个主要步骤组成:

    1. 开启事务:使用 MULTI 命令开启一个事务。之后的命令会被逐一入队,但不会立即执行。
    2. 入队命令:事务内的所有命令都会被入队,而不是立即执行。
    3. 执行事务:使用 EXEC 命令提交事务,所有入队的命令会按顺序执行。
    4. 取消事务:如果在事务执行之前,发现有问题,可以使用 DISCARD 命令取消事务,清空命令队列。

    # 示例:

    MULTI
    SET key1 "value1"
    INCR counter
    EXEC
    
    1
    2
    3
    4

    在这个示例中,SET key1 "value1" 和 INCR counter 两个命令会被顺序入队,直到 EXEC 命令执行时,这些命令才会按顺序执行。

    # 2. Redis事务的特性

    # 1. 单一性:

    Redis 事务没有隔离级别的概念,所有命令要么全部执行,要么一个也不执行。因此,Redis 事务要么成功,要么失败,不存在部分成功的情况。

    # 2. 事务的非原子性:

    虽然 Redis 在事务中保证命令的顺序执行,但并不能保证整个事务是原子的。每个命令是独立执行的,因此某些命令可能成功,而其他命令可能失败(如命令语法错误、数据类型错误等),而且 Redis 不会在事务中遇到错误时自动回滚已执行的命令。

    # 3. 乐观锁:

    Redis 支持 WATCH 命令,可以在事务开始前监视一个或多个键。如果在事务执行前这些键被其他客户端修改,事务将被中止,不会执行 EXEC 中的命令。这种机制被称为“乐观锁”。

    # 3. Redis事务的执行过程

    1. MULTI:开启事务。所有后续命令会被放入一个队列中,而不会立即执行。
    2. 命令入队:事务中的每个命令都会依次入队。
    3. WATCH(可选):在执行 EXEC 之前,监视一个或多个键。如果这些键在事务执行前发生了变化,事务将被取消。
    4. EXEC:提交事务,Redis 按顺序执行事务队列中的所有命令。如果有 WATCH,那么只有在监视的键未被修改的情况下才会执行。
    5. DISCARD:如果需要取消事务,可以使用 DISCARD 命令,清空事务队列,并取消 WATCH。

    # 4. Redis事务的局限性

    • 没有回滚机制:如果事务中的某个命令失败,Redis 不会自动回滚已执行的命令。例如,在执行 INCR key 时,如果键的类型不是整数,该命令将失败,但之前的命令仍会生效。
    • 没有隔离级别:传统数据库的事务有多个隔离级别(如读未提交、读已提交、可重复读、串行化),但 Redis 没有隔离级别的概念。这意味着事务中的命令仍然可能受到其他命令的影响。
    • 错误处理:由于 Redis 事务无法回滚,一旦事务执行,所有入队的命令将按照顺序执行,并且一旦某个命令出错,后续命令仍然会继续执行。

    # 5. 事务的典型应用场景

    • 乐观锁控制的并发更新:利用 WATCH 和事务,可以避免并发更新导致的数据不一致问题。
    • 批量操作:将多个命令作为一个批次执行,确保这些命令按顺序执行且不被打断。
    • 简单的原子操作组合:在一些需要原子性组合操作的场景中,事务可以确保多个操作的顺序性。

    # 示例:使用 WATCH 实现乐观锁

    WATCH balance
    val = GET balance
    if (val > 100) {
        MULTI
        DECR balance 100
        INCR purchase_count
        EXEC
    } else {
        UNWATCH
        # handle error
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    在这个例子中,WATCH balance 监视 balance 键。如果 balance 在事务提交之前被其他客户端修改,EXEC 将不会执行,事务将被中止。

    # 6. Redis事务与传统数据库事务的比较

    • 原子性:传统数据库事务是原子的,要么全部执行,要么全部回滚;而 Redis 事务无法回滚,只能确保命令顺序执行。
    • 隔离性:传统数据库提供了不同的隔离级别,Redis 没有隔离级别的概念,可能导致“脏读”或“不可重复读”的情况。
    • 一致性:Redis 通过 WATCH 提供类似于乐观锁的机制,确保在多客户端环境下的一致性。

    总结来说,Redis 的事务功能虽然简单,但在某些需要顺序执行多个命令或保证数据一致性的场景中仍然非常有用。根据具体业务需求,可以结合 WATCH 等机制来提高事务的可靠性。

    编辑 (opens new window)
    上次更新: 2024/09/13, 11:59:12
    redis持久化策略
    redis分布式锁

    ← redis持久化策略 redis分布式锁→

    最近更新
    01
    ceph分布式存储-对象存储(RGW)搭建
    10-27
    02
    ceph分布式存储-集群客户端连接
    10-27
    03
    ceph分布式存储-管理crushmap
    10-27
    更多文章>
    Theme by Vdoing
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式