2026-03-15 02:28:53
Redis事务通过MULTI、EXEC等命令实现多个操作的原子性执行,其核心机制是将命令缓存后批量执行,但与关系型数据库事务不同,不支持回滚且存在语法错误全失败、执行错误不中断、乐观锁失效等特性。
一、Redis基础事务的核心命令与机制Redis事务的核心命令包括MULTI、EXEC、WATCH、UNWATCH和DISCARD,其中基础事务通过MULTI和EXEC实现:

执行模式:
Redis事务是“指令串行化”,所有命令在EXEC前被缓存,执行时按顺序批量处理,期间其他客户端的命令不会干扰。
关系型数据库事务支持“部分执行”,可通过COMMIT或ROLLBACK控制提交或回滚。
错误处理:
Redis事务在缓存阶段若发现语法错误,整个事务会被拒绝执行(如MULTI后输入非法命令,EXEC会返回错误且不执行任何命令)。
执行阶段若部分命令失败(如对非字符串键执行INCR),已成功的命令不会回滚,仅返回错误信息。

语法错误导致全失败
问题:若事务中任一命令存在语法错误(如键名拼写错误),EXEC会返回错误,且所有命令均不执行。
示例:MULTISET key1 "value1"SETX key2 "value2" # 非法命令EXEC # 返回错误,key1和key2均未设置
解决:在MULTI前验证命令语法,或通过应用层逻辑拆分事务。
执行错误不中断事务
问题:若事务中部分命令执行失败(如对非列表键执行LPUSH),已成功的命令仍会生效,仅错误命令返回提示。
示例:MULTISET key1 "100"INCR key2 # key2非数字键,执行失败EXEC # 返回:1) "OK" 2) (error) ERR value is not an integer
解决:在事务前通过TYPE命令检查键类型,或使用WATCH监控键状态。
乐观锁失效(WATCH机制)
问题:若事务使用WATCH监控键,且其他客户端在事务执行前修改了该键,当前事务的EXEC会失败(返回nil)。
示例:# 客户端AWATCH key1val = GET key1MULTISET key1 val+1 # 假设应用层计算新值EXEC # 若客户端B在此期间修改了key1,则EXEC返回nil# 客户端BSET key1 "new_value" # 导致客户端A事务失败
解决:
重试事务:捕获EXEC失败后重新执行WATCH和事务流程。
避免长事务:缩短WATCH到EXEC的时间间隔,减少冲突概率。


Redis事务通过MULTI/EXEC实现命令的原子性执行,但需注意其与关系型数据库事务的差异(如无回滚、错误处理方式)。结合WATCH可实现乐观锁控制,但需处理冲突和超时问题。在实际应用中,应根据场景选择合适的事务模式或替代方案(如Lua脚本),以平衡一致性和性能需求。