深入理解两种数据库事务机制的核心差异与实现原理
MULTI:将客户端标记为事务状态,后续命令不会立即执行,而是放入事务队列。
命令队列:Redis 使用一个数组(multiState.commands)存储事务中的所有命令。
EXEC:遍历命令队列,依次执行每个命令。执行期间不会被其他客户端命令打断。
WATCH:实现乐观锁,监控键的变化。如果键被其他客户端修改,EXEC 会返回 nil 表示执行失败。
# 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
# 需要客户端实现重试逻辑