这里写目录标题
13.3 带有乐观锁的事务
本书在第2章实现了具有基本获取和释放功能的锁程序,并在第12章为 该程序加上了自动释放功能,但是这两个锁程序都有一个问题,那就是 它们的释放操作都是不安全的:
·无论某个客户端是否是锁的持有者,只要它调用release()方法,锁就 会被释放。
·在锁被占用期间,如果某个不是持有者的客户端错误地调用了 release()方法,那么锁将在持有者不知情的情况下释放,并导致系统 中同时存在多个锁。
为了解决这个问题,我们需要修改锁实现,给它加上身份验证功能:
·客户端在尝试获取锁的时候,除了需要输入锁的最大使用时限之外, 还需要输入一个代表身份的标识符,当客户端成功取得锁时,程序将把 这个标识符存储在代表锁的字符串键中。
·当客户端调用release()方法时,它需要将自己的标识符传给 release()方法,而release()方法则需要验证客户端传入的标识符与 锁键存储的标识符是否相同,以此来判断调用release()方法的客户端 是否就是锁的持有者,从而决定是否释放锁。
根据以上描述,我们可能会写出代码清单13-5所示的代码。
这个锁实现在绝大部分情况下都能够正常运行,但它的release()方法 包含了一个非常隐蔽的错误:在程序使用GET命令获取锁键的值以后, 直到程序调用DEL命令删除锁键的这段时间里面,锁键的值有可能已经 发生了变化,因此程序执行的DEL命令有可能会导致当前持有者的锁被 错误地释放。
举个例子,表13-1就展示了一个锁被错误释放的例子:客户端A是锁原 来的持有者,它调用release()方法尝试释放自己的锁,但是当客户端 A执行完GET命令并确认自己就是锁的持有者之后,锁键却因为过期而 自动被移除了,紧接着客户端B又通过执行acq