MySQL 面试:简述乐观锁以及悲观锁的区别以及使用场景

你曾被提过类似问题在面试中问过吗?或者将来会遇到,让我们一起探索和掌握它!

感谢您阅读这篇文章。更多面试问题:
https://programmerscareer.com/zh-cn/software-interview-set/

主题 1.1:MySQL 和锁定机制简介

让我们开始学习 MySQL 和锁定机制!

MySQL 是世界上最著名的开源关系数据库管理系统(RDBMS)之一。它非常受欢迎,特别是用于网站和在线出版的网络应用程序,并是 LAMP 开源网站应用程序软件堆栈的核心组件。

现在让我们谈谈为什么我们需要锁定机制在数据库中。 想象一场场景,两名人同时试图从同一银行账户中提款。 如果没有机制来防止它,他们可能会同时检查帐户余额,看到足够的资金,并继续提取超过帐户中实际存在的资金。 这是一种竞争条件,并可能导致严重的数据完整性问题。 这就是锁定机制发挥作用的地方!

主题 1.2:锁定机制概述

所以,让我们深入探讨 MySQL 中的锁定机制。 就像我们所说的,锁定在数据库中非常重要,特别是在多用户数据库环境中。

在 MySQL 中,锁定主要用于控制如何访问事务,以便每个事务可以看到数据的一致快照。 MySQL 中使用的主要类型的锁定有:

  1. 共享锁(读锁):共享锁用于执行读操作(选择)时。 它允许并发事务读取(选择)资源,并保证无事务可以写入(更新/删除)该资源。
  2. 排他锁(写锁):排他锁用于执行数据修改操作时。 它确保持有锁的事务是唯一的事务,可以读取或写入资源。

在下一章中,我们将深入探讨两种流行的锁定机制—— 乐观锁定和悲观锁定。 选择使用哪种锁定机制通常取决于系统的特定要求,例如并发事务可能会发生冲突的概率。

主题 1.3:了解乐观锁定

让我们来详细了解乐观锁定! 这是在多用户数据库中处理并发更新的策略。

乐观锁定基于多个事务可以完成而不会影响彼此的假设,因此允许多个事务访问同一条记录进行编辑。 这种方法在数据的争用较低的系统中很有用。

下面是乐观锁定的简单方法:

  1. 从数据库中获取记录以进行更新。
  2. 更新之前,应用程序会检查另一用户是否已更新该记录以来。
  3. 如果记录未被其他用户更新,应用程序可以执行更新并一切顺利进行。
  4. 如果记录已被其他用户更新,应用程序通常会通知用户并中止事务或自动重试事务。

乐观锁定的主要优点是其高效性。 它避免了获取和释放锁的开销并避免了事务等待锁。

但请记住,没有免费的午餐! 在数据争用较高并且数据更新频繁的环境中,可能会出现许多事务冲突,这可能会导致性能问题。

主题 1.4:了解悲观锁定

让我们来深入了解悲观锁定! 这是 MySQL 中基于完全不同的假设的机制。 它假设冲突很可能会发生并强制执行严格的控制来防止这种情况。

下面是悲观锁定的工作方式:

  1. 当获取记录以进行更新时,立即获取排他锁。
  2. 直到释放锁,其他事务不能更新此记录。
  3. 释放锁时,其他事务可以获取锁并更新此记录。

悲观锁定是防止冲突的绝佳方法,因为它不允许另一事务进行,如果它可能会导致冲突。 它适用于数据争用较高并且记录频繁更新的环境。

但请记住,每个硬币都有两面! 这种方法可能会导致降低并发性并影响系统性能,因为事务可能会被长时间保持等待锁。

主题1.5:比较乐观锁和悲观锁。

现在你已经熟悉了乐观锁和悲观锁,了解在哪些场景下使用哪一种可以显著影响应用的性能和可靠性。

乐观锁 假设冲突较少并大多数避免了锁的获取和释放。它可能在低争用场景下导致更高的性能,因为它会导致更少的阻塞。然而,对于经常发生冲突的系统,锁的成本和频率的回滚可能会降低性能。

另一方面,悲观锁 假设冲突会经常发生并使用锁来防止它们。这种策略可能在高争用场景下有好处,因为它避免了冲突解决相关的回滚。然而,获取锁所需的等待时间可能会降低性能。

因此, golden rule 是:

在冲突较少的情况下,选择乐观锁。在冲突经常发生的情况下,选择悲观锁。

这就是 MySQL 中乐观锁和悲观锁的简要比较。

主题1.6:锁定机制的使用场景

厉害!现在我们已经了解了主要的锁定机制,让我们来看看这些机制在真实的场景中可能会有好处。

  1. 银行系统
    考虑一种银行应用程序,其中经常发生交易。这些交易需要一致和安全。在这种情况下,悲观锁是有利的,因为它确保一旦用户开始交易,就不会有其他用户修改数据,保证数据一致性。

  2. 票务预订应用程序
    考虑一个在线票务预订系统,其中多个用户试图预订有限数量的票。在这种情况下,乐观锁可能是有利的,因为它允许多个用户同时访问票务预订功能。

  3. 内容管理系统
    如果你在一个内容管理系统上工作,其中用户正在更新他们的博文或文章,乐观锁可能是有利的。由于两个用户试图编辑同一文章的可能性相对较低,系统可以处理这些偶尔的冲突。

  4. 股票交易应用程序
    在一个股票交易应用程序上,悲观锁可能是有利的,因为它立即阻止其他交易,直到完成。在这种情况下,由于一次性的延迟可能会导致重大财务损失,悲观锁可能会有好处。

记住,决定使用乐观锁或悲观锁主要取决于应用的性质,冲突的可能性,并发性的要求,以及延迟的容忍度。

主题1.7 回顾和评估

  1. MySQL 和锁定机制的介绍:我们讨论了 MySQL 的功能,锁定机制的重要性和并发数据库访问的帮助。
  2. 锁定机制的概述:我们浏览了各种锁定机制,它们的重要性在维护数据一致性和处理并发访问中,并分析了它们的优缺点。
  3. 了解乐观锁定:我们深入探讨了乐观锁定的概念,它的优缺点和在 MySQL 中的实现。
  4. 了解悲观锁定:我们探讨了悲观锁定,包括其强项和在 MySQL 中的实现。
  5. 比较乐观和悲观锁定:我们比较了这两种锁定机制并结论了选择高度取决于特定的使用案例和系统要求。
  6. 锁定机制的使用场景:我们浏览了可能的真实应用场景,其中这些锁定机制可以提供好处。

例子问题:

让我们来看一个例子:你有一个 MySQL 数据库,其中一个名为“Account”的表存储了用户的账户余额。两个不同的金融事务试图从同一帐户中扣除资金同时进行。如何使用 MySQL 中的乐观和悲观锁定机制来处理这种情况?

答案

对于 乐观锁定,您可以通过在 Account 表中使用版本列来处理这种情况。这是怎样做的:

  • 事务先读取帐户余额并记下版本。在更新帐户之前,它们检查版本是否仍然相同。如果版本已更改,这意味着另一事务在此期间更新了帐户余额,因此当前事务被回滚。这样就避免了不一致的扣除。

对于 悲观锁定,您将锁定帐户对于每个金融事务。这是怎样做的:

  • 事务立即锁定帐户,在读取帐户余额时。只有一个事务可以持有锁,并持有它直到更新帐户余额。所有试图读取帐户余额的其他事务,当锁被持有时,将被阻止,直到锁被释放。

现在,测试你的知识。

**问题 1 (简单)**:

在哪种情况下会选择乐观锁定而不是悲观锁定?

**问题 2 (中等)**:

悲观锁定在高吞吐量系统中可能会有哪些缺点,并说明如何减轻这些缺点?

**问题 3 (困难)**:

描述一种场景,其中既不适合乐观锁定也不适合悲观锁定,并说明所需的锁定或并发控制机制。

English post: https://programmerscareer.com/mysql-interview5/
作者:Wesley Wei – Twitter Wesley Wei – Medium
注意:本文为作者原创,转载请注明出处。

为什么MySQL使用B+树进行索引? MySQL 面试:产生死锁的必要条件有哪些?如何解决死锁?

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×