Redis 中的 流水线与事务 带有乐观锁的事务 WATCH:对键进行监视 UNWATCH:取消对键的监视

本文介绍了Redis中带有乐观锁的事务,通过WATCH命令对键进行监视,防止在GET和DEL操作间键值发生变化导致错误释放。详细解释了WATCH的原理和使用,以及其与UNWATCH、事务的关系,最后提供了带有身份验证功能的锁和计数信号量的实现示例,确保资源管理的安全性。
摘要由CSDN通过智能技术生成

13.3 带有乐观锁的事务

        本书在第2章实现了具有基本获取和释放功能的锁程序,并在第12章为 该程序加上了自动释放功能,但是这两个锁程序都有一个问题,那就是 它们的释放操作都是不安全的:

        ·无论某个客户端是否是锁的持有者,只要它调用release()方法,锁就 会被释放。

        ·在锁被占用期间,如果某个不是持有者的客户端错误地调用了 release()方法,那么锁将在持有者不知情的情况下释放,并导致系统 中同时存在多个锁。

        为了解决这个问题,我们需要修改锁实现,给它加上身份验证功能:

        ·客户端在尝试获取锁的时候,除了需要输入锁的最大使用时限之外, 还需要输入一个代表身份的标识符,当客户端成功取得锁时,程序将把 这个标识符存储在代表锁的字符串键中。

        ·当客户端调用release()方法时,它需要将自己的标识符传给 release()方法,而release()方法则需要验证客户端传入的标识符与 锁键存储的标识符是否相同,以此来判断调用release()方法的客户端 是否就是锁的持有者,从而决定是否释放锁。

        根据以上描述,我们可能会写出代码清单13-5所示的代码。
请添加图片描述

        这个锁实现在绝大部分情况下都能够正常运行,但它的release()方法 包含了一个非常隐蔽的错误在程序使用GET命令获取锁键的值以后, 直到程序调用DEL命令删除锁键的这段时间里面,锁键的值有可能已经 发生了变化,因此程序执行的DEL命令有可能会导致当前持有者的锁被 错误地释放。

        举个例子,表13-1就展示了一个锁被错误释放的例子:客户端A是锁原 来的持有者,它调用release()方法尝试释放自己的锁,但是当客户端 A执行完GET命令并确认自己就是锁的持有者之后,锁键却因为过期而 自动被移除了,紧接着客户端B又通过执行acq

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值