事务
事务操作
Redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中会一次性,顺序性,排他性地执行一些列的命令.
==Redis单条命令是保证原子性的,但是事务不保证原子性==
==Redis事务没有隔离级别的概念==
redis的事务:
- 开启事务(multi)
- 命令入队(...)
- 执行事务(exec)
执行命令
127.0.0.1:6379> multi # 开启事务
OK
# 命令入队
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> get k1
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec # 执行事务
1) OK
2) OK
3) "v1"
4) OK
放弃命令
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> discard # 取消事务
OK
127.0.0.1:6379> get k4 # 事务队列中的命令都不会被执行
(nil)
- 编译性异常(代码有问题),事务中所有的命令都不会执行
- 运行时异常(代码没问题),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常
乐观锁
-
悲观锁 (Pessimistic Locking): 假设总会发生冲突,所以在操作数据前就将其锁定,阻止其他客户端访问。这可能导致性能瓶颈,因为其他客户端需要等待锁释放。
-
乐观锁 (Optimistic Locking): 假设冲突是小概率事件。它允许所有客户端读取数据,但在更新数据时会检查数据是否在读取后被修改过。如果被修改了,则更新失败,由客户端决定如何处理(通常是重试)。
WATCH
就是 Redis 实现乐观锁的方式。
WATCH
的细节与重点
-
原子性:
WATCH
本身不是原子操作的开始,它只是标记了需要监视的 key。真正的原子操作是EXEC
执行的事务队列。 -
监视的是值的改变:
WATCH
监控的是 key 对应的值是否被任何写命令(如SET
,INCR
,LPUSH
,HSET
等)修改。即使 key 的过期时间被改变 (如EXPIRE
), 或者 key 因为过期而被删除,也会被视为“改变”。 -
一次性触发: 一旦被
WATCH
的 key 发生改变,该客户端连接上的事务标记就会被设置(变为 "dirty")。后续的EXEC
就会失败。这个标记在EXEC
或DISCARD
之后会被清除。 -
WATCH
的范围:WATCH
命令的效果只持续到下一个EXEC
或DISCARD
命令。执行完EXEC
或DISCARD
后,之前所有WATCH
的 key 都会被自动UNWATCH
。如果你想在下一个事务中继续监视某些 key,你需要重新WATCH
它们。 -
客户端行为: Redis 服务器不负责重试。当
EXEC
返回nil
时,由客户端应用程序逻辑来决定是否以及如何重试事务。通常的模式是循环,直到事务成功或达到最大重试次数。
评论区
请登录后发表评论