Navicat 博客

关系数据库事务中的对象锁定 - 第 2 部分 2021 年 6 月 16 日,由 Robert Gravelle 撰写

悲观与乐观锁定

关系数据库系统(RDBMS)在修改(例如,更新或删除)表记录时采用各种锁定策略来强制实施事务 ACID 属性。有时,当两个并发事务无法进行时,可能会发生死锁,因为每个事务都在等待对方释放锁定。在本系列的第 1 部分中,我们知道了什么是关系数据库中的对象锁定、不同类型的锁定和死锁。在今天的后续文章中,我们将比较悲观锁定和乐观锁定的优缺点。

悲观锁定

当使用悲观锁定,资源在事务中第一次访问时开始一直被锁定,直到事务完成,在此期间其他事务无法访问它。在大多数事务只是读取而不更新资源的情况下,排他锁可能会导致更多的锁争用(死锁)。回想一下第 1 部分中的银行示例,一旦在交易中访问该帐户,它就会被锁定。任何在其他交易中使用该帐户的尝试都会导致其他进程被延迟,直到帐户锁定被释放,或者该进程交易将被取消并回滚到之前的状态。

乐观锁定

当使用乐观锁定,资源在第一次被事务访问时实际上并没有被锁定。相反,资源的初始状态会被持久化。其他事务仍然能够访问该资源,这使得冲突更改的可能性成为已知风险。在提交事务时,当持久化存储中的资源即将更新时,资源的状态会再次从存储中读取,并与在事务中首次访问资源时保存的状态进行比较。如果两种状态不同,则意味着进行了冲突更新,因此事务将会回滚。在我们的银行示例中,帐户的金额将在首次访问时保存。如果交易更改了帐户金额,则将在金额即将更新之前再次从存储中读取该金额。如果交易开始后金额发生了变化,交易本身就会失败,否则新的金额将保持不变并被保存。

在悲观锁定和乐观锁定之间做出决定

既然我们已经介绍了两种类型的锁定是什么,问题就变成了应该使用哪种。在大多数情况下,乐观锁定更有效并提供更高的性能。与此同时,悲观锁定提供了更好的数据完整性,但是,锁定的管理更难,因为遇到死锁的可能性更大。在悲观锁定和乐观锁定之间进行选择时,请考虑以下三个准则:

  • 如果有大量更新并且用户尝试同时更新数据的机会相对较高,则悲观锁定很有用。
  • 悲观锁定更适合包含经常更新的小型表的应用程序。在这些“热点”的情况下,冲突的可能性很大,以至于乐观锁定浪费了回滚冲突事务的气力。
  • 当发生冲突的可能性非常低时,乐观锁定很有用,即有很多记录但用户相对较少,或者很少更新而主要是读取操作。

总结

在这篇文章中,我们比较了悲观锁定与乐观锁定。在下一部分中,我们将探索从死锁情况中恢复的策略。



Rob Gravelle 居住在加拿大渥太华,是一名有 20 多年经验的 IT 专家。过往,Rob 曾为与情报有关的组织(如加拿大边境服务局和各种商业组织)构建系统。在业余时间,Rob 是一名出色的吉他演奏家,他拥有多张 CD 和数字发行版

Navicat 文章
频道条目
分享
文章归档