Redis附加功能-乐观锁

通过使用 MULTI 和 EXEC , 我们可以将多条命令放到一个事 务里面执行, 确保事务里面的命令要么全部都被执行, 要么就一个都不执行, 从而防止数据出错。但是有时候只使用事务还是无法保证数据的正确性, 这时候就需要使用 Redis 提供的乐观锁功能(Optimistic Locking)

命令
  • WATCH key [key …]
    如果被监视的键在事务提交之前(也即是 EXEC 命令执行之前), 已经被其他客户端抢先修改了, 那么服务器将拒绝执行客户端提交的事务, 并返回nil作为事务的回复

    127.0.0.1:6379> watch msg
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set msg haha
    QUEUED
    127.0.0.1:6379> exec
    (nil)
    复制代码

    在上个事务提交之前已执行:

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set msg hehe
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    复制代码

    结果:

    127.0.0.1:6379> get msg
    "hehe"
    复制代码
  • UNWATCH
    取消对所有键的监视

  • DISCARD
    放弃执行事务,并且取消对所有键的监视(相当于执行 UNWATCH)

乐观锁和悲观锁的区别

  • 乐观锁会对被加锁的数据进行监视,多个客户端可以同时尝试对数据进行修改,其中最先尝试的客户端会成功,而之后尝试的客户端则会失败
  • 悲观锁只让一个客户端对数据进行修改,而其他客户端则需要等待正在进行修改的客户端执行完毕之后,才能尝试获得修改权
  • 对于频繁进行读写操作的 Redis 来说,使用乐观锁可以避免客户端被阻塞:当一个客户端修改数据失败之后,它只要重试就可以了,这个过程不需要进行任何的等待

在这里插入图片描述

事务和乐观锁的缺陷
  • 对于一个的事务,通常需要仔细思考才能知道应该对哪些键进行加锁:锁了不应该锁的键会增加事务失败的机会,甚至可能会造成程序出 错;而忘了对应该锁的键进行加锁的话,程序又会产生竞争条件
  • 有时候为了防止竞争条件发生,即使操作本身不需要用到事务,但是为了让乐观锁生效,也会使用事务将命令包裹起来,这增加了实现的复杂度,并且带来了额外的性能损耗
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享