乐观vs.悲观locking
我理解乐观和悲观locking之间的区别。 现在有人可以向我解释什么时候我会使用任何一个?
而这个问题的答案会根据我是否使用存储过程来执行查询而发生变化吗?
*但只是为了检查,乐观意味着“不要在阅读时locking桌子”,而悲观的意思是“在阅读时locking桌子”。
乐观locking是一种读取logging,logging版本号(其他方法涉及date,时间戳或校验和/散列)的策略,并在将logging写回之前检查版本是否未更改。 当你把logging写回来时,过滤版本上的更新以确保它是primefaces的。 (即,当你检查版本和写入logging到磁盘之间没有更新),并在一击中更新版本。
如果logging脏(即与您的版本不同),则中止交易,用户可以重新启动。
此策略最适用于高容量系统和三层体系结构,在这种体系结构中,您不必为会话保持与数据库的连接。 在这种情况下,客户端无法实际维护数据库locking,因为连接是从池中取出的,并且您可能不会使用从一个访问点到另一个访问点的相同连接。
悲观locking是指当您lockinglogging以供专用时,直到完成logging为止。 它具有比乐观locking更好的完整性,但要求您在应用程序devise时要小心以避免死锁 。 要使用悲观locking,您需要直接连接到数据库(通常是两层客户机服务器应用程序中的情况)或者可以独立于连接使用的外部可用事务ID。
在后一种情况下,您使用TxID打开事务,然后使用该ID重新连接。 DBMS维护锁并允许您通过TxIDselect会话备份。 这就是如何使用两阶段提交协议(如XA或COM +事务 )的分布式事务。
乐观locking是用来当你不期望许多碰撞。 做一个正常的操作花费less,但如果发生碰撞,你会付出更高的代价来解决交易中止。
预计碰撞时使用悲观locking。 违反同步的交易将被阻止。
要select适当的locking机制,您必须估计读取和写入的数量并相应地进行规划
乐观的假设,当你阅读时没有什么会改变的。
悲观主义者认为,某事将会如此locking。
如果数据完全读取不是必须的,请使用乐观。 你可能会得到奇怪的“脏”阅读 – 但是导致僵局之类的可能性要小得多。
大多数Web应用程序都可以使用脏读取 – 在极less数情况下,数据并不完全符合下一次重新加载的要求。
对于确切的数据操作(如在许多金融交易中)使用悲观。 数据的准确读取是非常重要的,没有未显示的变化 – 额外的locking开销是值得的。
哦,微软的SQL服务器默认为页面locking – 基本上你正在阅读的行和几个方面。 行locking更准确,但速度更慢。 通常值得把你的事务设置为读取提交或不locking,以避免在读取时出现死锁。
除了已经说过的话,应该说乐观locking倾向于提高并发性而牺牲可预测性。 悲观locking倾向于降低并发性,但更具可预测性。
你付钱,等等
如果悲观locking是更好的select,我会再想一个例子。
为了乐观locking每个参与者在数据修改中必须同意使用这种locking。 但如果有人修改数据而不关心版本列,这将破坏乐观locking的整个想法。
基本上有两个最受欢迎的答案。 第一个基本上说
乐观需要一个三层体系结构,在这个体系结构中,你不必为会话保持与数据库的连接,而悲观locking是当你lockinglogging供你独占使用,直到你完成它。 它具有比乐观locking更好的完整性,您需要直接连接到数据库。
另一个答案是
乐观(版本控制)由于没有locking而更快,但是当争用率高时,(悲观)locking性能更好,最好是防止工作,而不是丢弃并重新开始。
要么
乐观locking在遇到罕见碰撞时效果最佳
因为它被放在这个页面上。
我创build了我的答案来解释“保持连接”与“低冲突”有关。
要了解哪种策略最适合您,请不要考虑您的数据库具有的每秒交易次数,而要考虑单个交易的持续时间。 通常情况下,您打开trasnaction,performa操作并closures交易。 这是一个简短的,经典的交易,ANSI已经考虑到了,并且可以放弃locking。 但是,如何实现许多客户同时预订相同房间/座位的订票系统呢?
您浏览优惠,填写许多可用选项和当前价格的表格。 这需要花费很多时间和选项可以过时,所有的价格之间的无效你开始填写表格,并按下“我同意”button,因为没有locking您访问的数据和其他人,更敏捷,已被意图改变所有的价格,你需要重新启动新的价格。
相反,您可以在读取它们时locking所有选项。 这是悲观的情况。 你明白为什么它很糟糕。 你的系统可以被一个简单的开始预约和吸烟的小丑打倒。 在他完成之前,没有人能保留任何东西。 你的现金stream量下降到零。 这就是为什么乐观的保留在现实中被使用。 那些花时间过长的人不得不以较高的价格重新开始预订。
在这个乐观的方法中,您必须logging您读取的所有数据(如在我的“重复读取”中 ),并使用您的数据版本来到提交点(我想以您在此报价中显示的价格购买股票,而不是当前价格)。 此时,创buildANSI事务,locking数据库,检查是否没有更改,并提交/中止您的操作。 国际海事组织,这是MVCC的有效仿真,这也与乐观CC相关联,也假定你的交易在中止的情况下重新启动,那么你将作出新的保留。 这里的交易涉及人类用户的决定。
我并不了解如何手动实现MVCC,但我认为长时间运行的重启选项是了解主题的关键。 纠正我,如果我错了任何地方。 我的回答是这个Alex Kuznecov章节的动机。
乐观locking的一个用例是让您的应用程序使用数据库来允许您的线程/主机之一“声明”任务。 这是一个定期派上用场的技术。
我能想到的最好的例子是使用数据库实现的任务队列,多个线程同时声明任务。 如果一个任务的状态是'Available','Claimed','Completed',那么一个db查询可以像“Set status ='Claimed'这样status ='Available'。如果多个线程试图以这种方式改变状态,除了第一个线程外,所有的数据都会因为脏数据而失败
请注意,这是一个只涉及乐观locking的用例。 因此,作为“不希望发生多次冲突时使用乐观locking”的替代scheme,也可以在您期望发生冲突的地方使用,但只需要一个事务成功。
在大多数情况下,乐观locking效率更高,性能更高。 在悲观和乐观locking之间进行select时,请考虑以下几点:
-
如果用户尝试同时更新数据的时候有很多更新和相对较高的机会,悲观locking是有用的。 例如,如果每个操作一次可以更新大量logging(银行可能会在每个月末向每个账户添加利息收入),并且两个应用程序同时运行这些操作,则它们将会发生冲突。
-
悲观locking在包含经常更新的小表的应用程序中也更为合适。 就这些所谓的热点而言,冲突很可能会导致乐观locking浪费在回滚冲突事务上的努力。
-
如果冲突的可能性非常低 – 有很多logging,但是用户相对较less,或者只有很less的更新和大部分读取types的操作,乐观locking非常有用。