【问题标题】:What happens to the Transaction waiting for the lock?等待锁的事务会发生什么?
【发布时间】:2021-12-12 21:32:53
【问题描述】:

我在一次采访中被问到,“在 MySQL 数据库中,如果 Transaction(2) 尝试获取共享/独占锁,但另一个 Transaction{1) 已经在同一资源上拥有独占锁,会发生什么情况?”

我的回答很简单,Transaction(2) 一直等到 Transaction(1) 的提交或回滚。然后是后续问题。 如果是这样,

  1. 第二个事务将在哪里等待。 (比如阻塞队列类型的实现?)
  2. 如何在事务提交或回滚时通知第二个事务(1)?
  3. 如果有多个事务在等待被 Transaction(1) 锁定的同一资源,如何解决锁定问题?

【问题讨论】:

  • 这是 MySQL 问题还是 Postgres 问题之一或两者兼而有之?
  • 这是一般 DBMS 问题。所以两者兼而有之。如果我们确实需要一个答案,我们可以假设这是一个 MySQL 数据库。
  • 引擎可以确定存在死锁并可以中止一个或多个等待事务。

标签: mysql transactions locking


【解决方案1】:

这类问题与 SQL 语言无关,而与具体实现有关。例如 MySQL 与 PostgreSQL 中的行为可能会有所不同。

我可以回答 MySQL 案例。

如果您在事务 2 中执行查询,您的客户端会调用 API 函数并等待它返回。它在等待查询执行时不会返回。这是典型的函数调用。

如果您的事务需要事务 1 已持有的锁,则您的 API 调用会阻塞。也就是说,查询在等待锁定时不会开始执行。

MySQL 的 InnoDB 存储引擎的默认锁定等待超时为 50 秒(这是可配置的)。如果在超时之前无法获取锁,则查询失败,API 调用返回错误。

事务回滚。您可以在同一事务范围内重试给定查询。

MySQL 还支持作为表锁的“元数据锁”,这与 InnoDB 的行锁不同。元数据锁用于诸如 DROP TABLE 或 ALTER TABLE 之类的语句,它会等待直到没有事务读取或写入表。同样,如果 DDL 语句持有独占元数据锁,则查询无法获取元数据锁。元数据锁也有超时,但它的默认值要长得多:它是 31536000 秒(1 年)。

【讨论】:

    猜你喜欢
    • 2017-08-15
    • 2012-09-11
    • 1970-01-01
    • 2014-11-22
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    相关资源
    最近更新 更多