Redis 确实支持事务,它通过 MULTI
、EXEC
、DISCARD
和 WATCH
四个命令来实现事务功能。以下是 Redis 事务的详细介绍:
一、事务的基本使用
- 开启事务:使用
MULTI
命令标记一个事务块的开始。一旦进入事务块,所有后续命令都会被放入队列中等待执行,而不是立即执行。 - 命令入队:在事务块内,每个命令会被依次放入队列中,并返回
"QUEUED"
字符串表示该命令已成功加入队列。 - 执行事务:当调用
EXEC
命令时,Redis 会按顺序执行事务块内的所有命令,并将结果以数组形式返回。如果某个命令在事务中出错,其他命令仍会被执行,但错误的命令不会影响其他命令的结果。 - 取消事务:使用
DISCARD
命令可以取消事务,即清空事务队列中的所有命令并退出事务状态。
二、示例代码
# 开启事务
MULTI
# 添加命令到事务队列
SET key1 "value1"
# 输出: QUEUED
INCR key1
# 输出: QUEUED
# 执行事务
EXEC
# 输出:
# 1) OK
# 2) (error) ERR value is not an integer or out of range
在这个例子中,尽管 INCR key1
命令因为尝试对字符串值进行递增操作而失败,但是 SET key1 "value1"
依然被执行了。
三、乐观锁与 WATCH
Redis 提供了 WATCH
命令用于支持乐观锁的概念。WATCH
可以监控一个或多个键,在执行 EXEC
命令之前,如果这些键被其他客户端修改过,那么整个事务将会被取消(EXEC
返回 nil
),这允许你重新尝试事务或者采取其他措施。
- 使用
WATCH
监控某些键。 - 如果在
WATCH
后和EXEC
前,这些键没有被其他客户端改变,则事务正常执行。 - 如果有任意一个键被修改,
EXEC
将不会执行事务,并返回空回复。
四、事务的特性
- 原子性:Redis 事务不支持回滚,即要么全部命令执行成功,要么部分命令执行失败但仍继续执行其余命令。不同于传统数据库事务的全有或全无原则。
- 隔离性:Redis 使用单线程模型处理命令,因此事务具有天然的隔离性。
- 持久性:依赖于 Redis 的持久化机制(如 RDB 或 AOF)。
五、注意事项
- 在事务中,Redis 不会检查命令的语法正确性,所有的命令会在
EXEC
被调用后才真正执行,因此错误只能在执行阶段发现。 - Redis 事务中的命令是按照它们被添加的顺序依次执行的。
- 使用
WATCH
实现乐观锁时,需要考虑重试逻辑,以应对并发冲突的情况。
通过上述机制,Redis 提供了一种轻量级的事务处理方式,适用于那些不需要严格 ACID 特性的场景。
THE END