🔴 Redis 事务 vs 🔵 MySQL 事务

深入理解两种数据库事务机制的核心差异与实现原理

🔴

Redis 事务

  • 命令队列机制
    MULTI/EXEC 将命令打包顺序执行
  • 无回滚机制
    执行错误不会回滚已执行的命令
  • 隔离性保证
    事务执行期间不会被其他命令打断
  • ~
    弱一致性
    语法错误会拒绝,运行时错误继续执行
  • 高性能
    无锁设计,单线程执行无竞争
🔵

MySQL 事务

  • 完整 ACID
    原子性、一致性、隔离性、持久性
  • 支持回滚
    ROLLBACK 可撤销所有已执行操作
  • 多隔离级别
    读未提交/读已提交/可重复读/串行化
  • 强一致性
    任何错误都会导致整个事务失败
  • 🔒
    锁机制
    行锁、表锁保证并发安全

🎯 核心区别详解

1. 原子性 (Atomicity)

🔴 Redis
"要么全部执行,要么全部不执行"仅适用于命令入队阶段。一旦 EXEC,命令会全部执行,即使中间出错也不会回滚。
🔵 MySQL
真正的原子性。任何步骤失败都会触发回滚,数据库状态回到事务开始前。

2. 错误处理

🔴 Redis
语法错误(入队时)→ 拒绝执行;运行时错误(如类型错误)→ 继续执行后续命令。
🔵 MySQL
任何错误都会终止事务,可选择回滚或提交。约束违反会立即报错。

3. 隔离级别

🔴 Redis
单线程模型天然提供串行化隔离级别,无脏读、不可重复读、幻读问题。
🔵 MySQL
支持 4 种隔离级别,通过 MVCC 和锁机制实现,需根据场景选择。

4. 使用场景

🔴 Redis
批量操作、乐观锁(WATCH)、简单原子操作。不适合复杂业务事务。
🔵 MySQL
金融交易、订单处理、库存扣减等需要强一致性的业务场景。

🔧 Redis 事务实现机制

1
MULTI
开启事务
标记客户端进入事务模式
2
命令入队
QUEUE
命令进入事务队列
3
EXEC
执行事务
原子性执行队列命令
4
结果返回
RESULT
返回执行结果数组

📋 事务命令队列

点击"开始演示"查看事务执行流程
已入队
已执行
已丢弃

💡 实现原理说明

MULTI:将客户端标记为事务状态,后续命令不会立即执行,而是放入事务队列。

命令队列:Redis 使用一个数组(multiState.commands)存储事务中的所有命令。

EXEC:遍历命令队列,依次执行每个命令。执行期间不会被其他客户端命令打断。

WATCH:实现乐观锁,监控键的变化。如果键被其他客户端修改,EXEC 会返回 nil 表示执行失败。

⚖️ ACID 特性对比

A

原子性

🔴 Redis:部分支持
入队阶段原子,执行阶段不回滚
🔵 MySQL:完全支持
完整回滚机制
C

一致性

🔴 Redis:弱一致性
运行时错误不中断
🔵 MySQL:强一致性
约束检查严格
I

隔离性

🔴 Redis:串行化
单线程天然隔离
🔵 MySQL:多级别
MVCC + 锁实现
D

持久性

🔴 Redis:依赖配置
RDB/AOF 决定
🔵 MySQL:完全支持
Redo Log 保证

📝 代码示例对比

# Redis 事务示例 - 转账操作
# 使用 WATCH 实现乐观锁

WATCH account:a account:b      # 监控两个账户

balance_a = GET account:a      # 获取余额
if balance_a >= 100:
    MULTI                      # 开启事务
    DECRBY account:a 100      # 扣款
    INCRBY account:b 100      # 加款
    result = EXEC              # 执行事务
    
    if result == nil:          # 监控的键被修改
        # 事务失败,需要重试
        retry_transaction()
else:
    UNWATCH                    # 取消监控

# 注意:如果 EXEC 前键被修改,EXEC 返回 nil
# 需要客户端实现重试逻辑