2026-07-12 11:50:15
Redis事务是Redis提供的一种将多个命令打包执行、确保中间不被其他命令干扰的机制,但功能简单且不支持回滚,通常不推荐在生产环境中使用,但面试中常被问到。以下从设计目的、基本指令、乐观锁机制、错误处理及不支持回滚的原因等方面展开介绍:
1. Redis事务的设计目的Redis单个命令具有原子性(如GET、SET、MGET、MSET等),但涉及多个命令时,若需保证多个操作“要么全部成功,要么全部失败”,则需要事务机制。例如:用户A向用户B转账10元,需同时完成“A的余额-10”和“B的余额+10”两个操作,事务可确保这两个操作的原子性。
2. Redis事务的基本指令与用法Redis提供5个事务相关指令,核心流程为开启事务→添加命令→执行/放弃:
案例演示:
# 初始化数据127.0.0.1:6379> SET zhaocai 100 # 用户A余额OK127.0.0.1:6379> SET tuoluo 100 # 用户B余额OK# 开启事务并执行转账127.0.0.1:6379> MULTIOK127.0.0.1:6379(TX)> DECRBY zhaocai 10 # A余额-10QUEUED127.0.0.1:6379(TX)> INCRBY tuoluo 10 # B余额+10QUEUED127.0.0.1:6379(TX)> EXEC1) (integer) 90 # A余额结果2) (integer) 110 # B余额结果3. 乐观锁机制:WATCH与CAS问题场景:若事务执行期间,其他客户端修改了被监视的键,可能导致数据不一致。例如:
Client1开启事务,监视zhaocai和tuoluo。
Client2在Client1执行EXEC前修改了tuoluo的余额。
Client1的事务仍会执行,导致最终结果错误。
解决方案:WATCH指令实现CAS(Compare-And-Swap)乐观锁:
事务开启前监视键,若键在EXEC前被修改,事务取消。
UNWATCH可取消监视。
案例演示:
# Client1监视键并开启事务127.0.0.1:6379> WATCH zhaocai tuoluoOK127.0.0.1:6379> MULTIOK127.0.0.1:6379(TX)> DECRBY zhaocai 10QUEUED127.0.0.1:6379(TX)> INCRBY tuoluo 10QUEUED# Client2修改tuoluo的余额(模拟并发冲突)# (在另一个终端执行)127.0.0.1:6379> SET tuoluo 200OK# Client1执行事务(因tuoluo被修改,事务取消)127.0.0.1:6379(TX)> EXEC(nil) # 返回nil表示事务失败4. 事务执行错误的处理事务错误分为两类,处理方式不同:
EXEC前错误(如命令语法错误):
命令无法进入队列,事务直接取消,所有命令均不执行。
127.0.0.1:6379> MULTIOK127.0.0.1:6379(TX)> SET tuoluo # 缺少value参数,语法错误(error) ERR wrong number of arguments for 'set' command127.0.0.1:6379(TX)> EXEC(error) EXECABORT Transaction discarded because of previous errors.EXEC后错误(如类型错误):
错误命令不执行,其他命令仍执行,不满足原子性。
127.0.0.1:6379> MULTIOK127.0.0.1:6379(TX)> SET tuoluo 100 # String类型QUEUED127.0.0.1:6379(TX)> LPOP tuoluo # 对String执行List命令,类型错误QUEUED127.0.0.1:6379(TX)> EXEC1) OK # SET命令成功2) (error) WRONGTYPE # LPOP命令失败Redis官方明确表示事务不支持回滚,核心原因如下:
官方原文:
总结Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, not in production.(Redis命令仅在语法错误或类型不匹配时失败,此类错误通常在开发阶段即可发现,而非生产环境问题。)
Redis事务提供了一种轻量级的命令打包执行机制,但功能有限(不支持回滚、部分错误不保证原子性),通常建议通过Lua脚本或应用层逻辑实现更复杂的数据一致性需求。面试中需重点掌握: