我理解乐观锁定和悲观锁定之间的区别。现在,谁能给我解释一下,我一般什么时候使用这两种方法?

这个问题的答案是否会随着我是否使用存储过程来执行查询而变化?

但是为了检查一下,乐观的意思是“阅读时不要锁定表”,而悲观的意思是“阅读时锁定表”。


当前回答

更实际的一点是,在更新分布式系统时,DB中的乐观锁定可能不足以在分布式系统的所有部分之间提供所需的一致性。

例如,在AWS上构建的应用程序中,数据通常同时存在于DB(例如DynamoDB)和存储(例如S3)中。如果一个更新同时涉及DynamoDB和S3, DynamoDB中的乐观锁定仍然可能使S3中的数据不一致。在这种情况下,使用在DynamoDB中持有的悲观锁可能更安全,直到S3更新完成。事实上,AWS为此目的提供了一个锁定库。

其他回答

在大多数情况下,乐观锁定的效率更高,性能也更高。在悲观锁定和乐观锁定之间进行选择时,请考虑以下因素:

Pessimistic locking is useful if there are a lot of updates and relatively high chances of users trying to update data at the same time. For example, if each operation can update a large number of records at a time (the bank might add interest earnings to every account at the end of each month), and two applications are running such operations at the same time, they will have conflicts. Pessimistic locking is also more appropriate in applications that contain small tables that are frequently updated. In the case of these so-called hotspots, conflicts are so probable that optimistic locking wastes effort in rolling back conflicting transactions. Optimistic locking is useful if the possibility for conflicts is very low – there are many records but relatively few users, or very few updates and mostly read-type operations.

基本上有两个最流行的答案。第一个基本上是说

乐观需要一个三层架构,在这个架构中,您不必为会话维护到数据库的连接,而悲观锁定则是当您锁定记录供您独占使用时,直到您完成它。它比乐观锁有更好的完整性,你需要直接连接到数据库。

另一个答案是

乐观(版本控制)更快,因为没有锁定,但(悲观)锁定在争用很高时表现更好,并且最好是防止工作,而不是放弃它并重新开始。

or

乐观锁定在很少发生碰撞时效果最好

正如写在这一页上的。

我创造了我的答案来解释“保持联系”与“低碰撞”之间的关系。

要了解哪种策略最适合您,不要考虑您的DB具有的每秒事务数,而是考虑单个事务的持续时间。通常情况下,您打开交易,执行操作并关闭交易。这是ANSI心目中一个简短的、经典的事务,可以很好地摆脱锁定。但是,如何实现许多客户同时预订相同房间/座位的票务预订系统呢?

你浏览这些优惠,在表格中填写大量可用的选项和当前价格。这需要花费大量时间,选项可能会过时,在你开始填写表格并按下“我同意”按钮之间,所有价格都无效,因为你访问的数据没有锁定,其他人更灵活,已经干涉更改了所有价格,你需要重新启动新的价格。

相反,您可以在阅读时锁定所有选项。这是一个悲观的情景。你知道为什么这么糟糕了吧。你的系统可以被一个小丑搞垮,他只是简单地开始预订,然后抽烟。没有人可以在他完成之前预订任何东西。你的现金流降为零。这就是为什么在现实中使用乐观保留。那些拖延太久的人不得不以更高的价格重新开始预订。

In this optimistic approach you have to record all the data that you read (as in mine Repeated Read) and come to the commit point with your version of data (I want to buy shares at the price you displayed in this quote, not current price). At this point, ANSI transaction is created, which locks the DB, checks if nothing is changed and commits/aborts your operation. IMO, this is effective emulation of MVCC, which is also associated with Optimistic CC and also assumes that your transaction restarts in case of abort, that is you will make a new reservation. A transaction here involves a human user decisions.

我远没有理解如何手动实现MVCC,但我认为具有重新启动选项的长时间运行的事务是理解这个主题的关键。如果我哪里说错了,请指正。我的回答是受到Alex Kuznecov这一章的启发。

更实际的一点是,在更新分布式系统时,DB中的乐观锁定可能不足以在分布式系统的所有部分之间提供所需的一致性。

例如,在AWS上构建的应用程序中,数据通常同时存在于DB(例如DynamoDB)和存储(例如S3)中。如果一个更新同时涉及DynamoDB和S3, DynamoDB中的乐观锁定仍然可能使S3中的数据不一致。在这种情况下,使用在DynamoDB中持有的悲观锁可能更安全,直到S3更新完成。事实上,AWS为此目的提供了一个锁定库。

乐观锁定的一个用例是让应用程序使用数据库允许其中一个线程/主机“声明”任务。这是一个经常为我派上用场的技巧。

我能想到的最好的例子是使用数据库实现的任务队列,多个线程同时声明任务。如果一个任务有状态'Available', 'Claimed', 'Completed', db查询可以这样说:Set status='Claimed' where status='Available'。如果多个线程试图以这种方式改变状态,那么除了第一个线程之外,其他线程都会因为脏数据而失败。

注意,这是一个只涉及乐观锁定的用例。因此,作为“乐观锁定用于不期望有太多冲突的情况”的替代说法,它也可以用于您期望有冲突但只希望一个事务成功的情况。

乐观锁定和悲观锁定是数据库中锁定数据的两种模型。

乐观锁定:仅在向数据库提交更改时才锁定记录。

悲观锁定:在编辑记录时锁定记录。

注意:在两种数据锁定模型中,锁都是在将更改提交给数据库后释放的。