xDocxDoc
AI
前端
后端
iOS
Android
Flutter
AI
前端
后端
iOS
Android
Flutter
  • Redis 新手指南

    • Redis 概览
    • Redis 基础
    • Redis 高级用法与进阶指南
    • Redis基本事务操作详解

Redis基本事务操作详解

📌 一、事务基本概念与命令

Redis 事务通过以下命令实现多个操作的顺序化原子执行(命令队列整体执行,但无传统数据库的回滚机制):

  1. MULTI
    • 开启事务,后续命令进入队列而非立即执行,返回 QUEUED 表示入队成功。
  2. EXEC
    • 提交事务,按顺序执行队列中所有命令,返回每个命令的结果数组。
  3. DISCARD
    • 取消事务,清空队列中的命令。
  4. WATCH key...
    • 监视键值,若被监视的键在事务提交前被修改,事务自动失败(乐观锁实现)。
  5. UNWATCH
    • 取消所有键的监视。

⚙️ 二、事务执行流程

  1. 开启事务
    127.0.0.1:6379> MULTI   # 开启事务
    OK
  2. 命令入队
    127.0.0.1:6379> SET user:A 500  # 命令加入队列
    QUEUED
    127.0.0.1:6379> INCR user:B 100
    QUEUED
  3. 提交或取消
    • 提交(EXEC):
      127.0.0.1:6379> EXEC
      1) OK    # SET 成功
      2) (integer) 100  # INCR 成功
    • 取消(DISCARD):
      127.0.0.1:6379> DISCARD  # 清空队列
      OK

⚠️ 三、事务错误处理

Redis 事务错误分为两类,处理方式不同:

  1. 入队错误(语法错误)
    • 命令入队时检测到语法错误(如命令不存在),整个事务被拒绝执行。
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> SET key1 "value"
    QUEUED
    127.0.0.1:6379> NONEXISTING_CMD  # 错误命令
    (error) ERR unknown command
    127.0.0.1:6379> EXEC
    (error) EXECABORT  # 事务取消
  2. 执行错误(运行时错误)
    • 命令执行时出错(如对字符串执行 INCR),错误命令失败,其他命令继续执行(无回滚)。
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> SET key1 "hello"
    QUEUED
    127.0.0.1:6379> INCR key1  # 类型错误
    QUEUED
    127.0.0.1:6379> SET key2 "world"
    QUEUED
    127.0.0.1:6379> EXEC
    1) OK  # 成功
    2) (error) ERR value is not an integer  # 失败
    3) OK  # 成功

🔒 四、WATCH 乐观锁机制

作用:解决并发冲突,确保事务执行期间被监视的键未被修改。
流程:

  1. 使用 WATCH 监视键(如余额)。
  2. 开启事务并提交命令。
  3. 若监视键被其他客户端修改,EXEC 返回 nil 表示事务失败。

Java 示例(Jedis):

jedis.watch("balance");  // 监视余额
int balance = Integer.parseInt(jedis.get("balance"));
if (balance >= 100) {
    Transaction tx = jedis.multi();
    tx.decrBy("balance", 100);  // 扣款
    tx.incrBy("debt", 100);     // 增加债务
    tx.exec();  // 提交事务(若 balance 被修改则失败)
} else {
    System.out.println("余额不足");
}

失败处理:事务失败需客户端重试(如循环重试或补偿机制)。


🔄 五、Redis 事务 vs. 传统数据库事务

特性Redis 事务传统数据库事务
原子性队列整体原子执行,但单命令失败无回滚完全原子性(回滚支持)
隔离性无隔离级别,WATCH 实现乐观锁支持多级别隔离(如读已提交)
持久性依赖持久化配置(RDB/AOF)事务提交即持久化
执行时机命令在 EXEC 时一次性执行命令实时执行

🧩 六、适用场景与限制

  1. 适用场景
    • 批量操作:如转账(A 减余额,B 加余额)。
    • 并发控制:结合 WATCH 实现库存扣减、抢购。
  2. 限制与规避
    • 无回滚机制:需自行实现补偿逻辑(如日志记录 + 重试)。
    • 阻塞命令禁用:事务中不可用 BLPOP 等阻塞命令。
    • 集群限制:事务中所有键必须位于同一节点(相同 hash slot)。
  3. 替代方案
    • Lua 脚本:原子执行复杂逻辑(如库存扣减 + 日志记录):
      local stock = redis.call('GET', KEYS[1])
      if tonumber(stock) >= tonumber(ARGV[1]) then
          redis.call('DECRBY', KEYS[1], ARGV[1])
          return 1  -- 成功
      else
          return 0  -- 库存不足
      end

💎 总结

Redis 事务的核心价值在于 命令队列的顺序原子执行 与 WATCH 乐观锁的并发控制:

  • 基础操作:掌握 MULTI/EXEC/DISCARD 的事务生命周期管理。
  • 错误处理:区分入队错误(事务取消)与执行错误(部分成功)。
  • 生产实践:
    • 高并发场景优先使用 WATCH + 重试机制。
    • 复杂事务用 Lua 脚本替代(原子性更强)。
    • 避免大事务阻塞服务器,保持命令简洁。

通过合理设计重试逻辑与补偿机制,可在保证性能的同时实现业务一致性。

最后更新: 2025/8/26 10:07
Prev
Redis 高级用法与进阶指南