Redis事务的基本概念
Redis事务允许将多个命令打包成一个单元,按顺序执行而不会被其他客户端打断。通过MULTI、EXEC、DISCARD和WATCH命令实现事务功能。
事务中的命令在MULTI之后排队,直到EXEC被调用时才会执行。若过程中需要取消事务,使用DISCARD清空命令队列。WATCH命令用于监控键,若键在事务执行前被修改,事务将不会执行。
事务的执行流程
-
开启事务
使用MULTI命令标记事务开始,后续命令会被放入队列而非立即执行。 -
命令入队
客户端发送的操作命令(如SET、GET等)会被服务器缓存到队列中。 -
执行或丢弃
调用EXEC执行队列中的所有命令,或通过DISCARD清空队列并退出事务。 -
乐观锁控制(可选)
结合WATCH监视指定键,若这些键在EXEC前被其他客户端修改,则当前事务自动失效。
事务的特性
- 原子性:事务中的命令要么全部执行,要么全部不执行。但Redis事务不支持回滚,即使某条命令失败,后续命令仍会继续执行。
- 隔离性:事务执行期间不会被其他客户端命令打断。
- 无一致性保证:错误命令(如语法错误)会导致部分执行,需开发者自行处理。
事务的典型应用场景
-
批量操作
需要原子性执行多个命令时(如转账:扣减余额并增加目标账户余额)。 -
乐观锁控制
通过WATCH监视库存键,防止超卖:
WATCH inventory
val = GET inventory
IF val > 0
MULTI
DECR inventory
EXEC
ELSE
UNWATCH
- 流水线优化
事务命令队列可减少网络往返时间(RTT),提升批量操作的性能。
事务与Lua脚本的对比
| 特性 | 事务 | Lua脚本 | |---------------|------------------------------|----------------------------| | 原子性 | 命令级别 | 脚本级别(完全原子) | | 复杂性 | 简单命令组合 | 支持逻辑控制(if/for等) | | 网络开销 | 多次RTT(MULTI+命令+EXEC) | 单次RTT | | 错误处理 | 部分失败继续执行 | 出错时整体回滚 | | 适用场景 | 简单批量操作 | 需要复杂逻辑的原子操作 |
事务的局限性
-
无回滚机制
语法错误(如命令不存在)会导致EXEC时部分执行,运行时错误(如对字符串执行INCR)不会影响其他命令。 -
无隔离级别
事务期间的数据修改对其他客户端立即可见,不满足传统数据库的隔离性。 -
性能影响
长时间运行的事务会阻塞其他客户端,WATCH的键过多可能降低性能。
最佳实践建议
- 优先考虑Lua脚本处理需要原子性的复杂逻辑。
- 避免在事务中包含耗时操作,防止阻塞Redis单线程。
- 对WATCH的键数量保持谨慎,通常监控1-3个关键键即可。
- 事务中避免依赖前面命令的结果,因所有命令在EXEC时才实际执行。

被折叠的 条评论
为什么被折叠?



