【问题标题】:Unable to apply read or write lock manually into Innodb table via mysql command line无法通过 mysql 命令行手动将读取或写入锁应用于 Innodb 表
【发布时间】:2019-12-19 03:41:21
【问题描述】:

我正在尝试在表格锁定的情况下测试一个场景。

我尝试应用这样的读写锁 -

mysql> lock tables table_name write;
Query OK, 0 rows affected (0.01 sec)

但在此之后能够写 -

mysql> insert into table_name (id) values (1000000023);
Query OK, 1 row affected (0.00 sec)

读锁也不起作用。应用锁后,我能够成功地进行选择查询。

当我们对大量数据进行表迁移时,我需要测试我的应用程序行为(RESTful API),此时可能在表上应用了写锁。所以,我想,如果我能够通过命令行设置锁,它也将适用于我的 API。我使用相同的用户登录命令行,就像我在我的应用程序中使用登录 mysql。

如果我遗漏了什么,请告诉我。

表是 InnoDb 类型的。

【问题讨论】:

    标签: mysql table-locking


    【解决方案1】:

    我认为您误解了表锁定。根据documentation

    MySQL 允许客户端会话显式获取表锁,以便与其他会话协作以访问表,或防止其他会话在会话需要独占访问表的期间修改表。会话只能为自己获取或释放锁。一个会话无法获取另一个会话的锁或释放另一个会话持有的锁。

    您基本上锁定了 其他 个会话,使其无法写入表,但您仍然可以在持有锁的同时对其进行写入。

    对于您正在做的事情,该文档页面中有一个example

    对事务表(例如 InnoDB 表)使用 LOCK TABLES 和 UNLOCK TABLES 的正确方法是使用 SET autocommit = 0(不是 START TRANSACTION)开始事务,然后是 LOCK TABLES,直到您明确提交事务。例如,如果您需要写入表 t1 并从表 t2 读取,您可以这样做:

    SET autocommit=0;
    LOCK TABLES t1 WRITE, t2 READ, ...;
    ... do something with tables t1 and t2 here ...
    COMMIT;
    UNLOCK TABLES;
    

    当您调用 LOCK TABLES 时,InnoDB 内部会使用自己的表锁,而 MySQL 会使用自己的表锁。 InnoDB 在下一次提交时释放它的内部表锁,但是要让 MySQL 释放它的表锁,你必须调用 UNLOCK TABLES。你不应该让 autocommit = 1,因为 InnoDB 在调用 LOCK TABLES 后立即释放它的内部表锁,死锁很容易发生。如果 autocommit = 1,InnoDB 根本不会获取内部表锁,以帮助旧应用程序避免不必要的死锁。

    【讨论】:

    • 是的,我误解了这个概念。谢谢。但是,从用例的角度来看,这里的许多概念似乎仍然难以掌握和理解。你能推荐一些很好的视频教程吗?
    猜你喜欢
    • 1970-01-01
    • 2012-10-14
    • 2014-05-01
    • 2023-04-08
    • 1970-01-01
    • 2011-09-30
    • 2011-09-21
    • 2019-05-14
    • 2011-04-24
    相关资源
    最近更新 更多