【问题标题】:Locking during a transaction in MySQL InnoDB在 MySQL InnoDB 中的事务期间锁定
【发布时间】:2016-06-15 00:36:32
【问题描述】:

我想知道在 MySQL (InnoDB) 中的一个事务中修改的所有表是否对整个事务都被锁定?

我有一个会话更新版本表中的“最新版本”,然后为新版本的几 GB 数据创建一个新表。另一个会话始终获取最新版本,然后是该最新版本的数据;我发现这个会话有时会返回 0 行数据。

这是一个简化的 SQL 示例:

会话 1

假设我们已经有一个表data_v41,而version_table 中的latest_version 是41。这个会话是将数据更新到最新版本。

BEGIN TRANSACTION;

-- Increment the latest version...
UPDATE version_table SET latest_version = 42;

-- Create a new table for loads of data...
CREATE TABLE data_v42 (id int NOT NULL AUTO_INCREMENT, data TEXT);

-- Insert a few GBs of data here (so this is quite slow to write to disk)...
INSERT INTO data_v42 VALUES (...);
INSERT INTO data_v42 VALUES (...);
...

COMMIT;

会话 2

此会话从版本表中读取最新版本,然后使用该编号选择要从中读取最新数据的表:

-- Say this returns 42 and we use that number in the 2nd query...
SELECT latest_version FROM version_table;

-- Is it possible for this query to return 0 rows?
SELECT * FROM data_v42;

会话 2 有时似乎返回 0 行数据,这让我相信最新版本是在任何数据插入新表之前设置的。这似乎不适合原子事务......

在插入所有 GB 数据后,我是否需要重新安排 Session 1 中的查询以更新版本?

【问题讨论】:

  • Create table 这样的DDL-Statements 将结束事务并执行自动提交。您可以先创建表,然后启动事务。第二个事务是否能看到新数据取决于你的事务级别。
  • 谢谢,我不知道CREATE TABLE 会结束交易。我有默认的事务级别 (REPEATABLE READ)。
  • 我也刚刚在文档中找到了这个:dev.mysql.com/doc/refman/5.7/en/implicit-commit.html - 让您的评论成为答案,我会接受! :)
  • data_v42 -- 嗯,闻起来你正在生成很多相同的表?在 SQL 中不是一个好的设计模式。

标签: mysql transactions locking innodb acid


【解决方案1】:

为了在 session2 中反映您的数据,您需要重新排序这些查询

由于提交是在插入所有数据之后进行的,因此事务可能需要一些时间,这取决于数据和您插入的数据量

因此,该表在您的其他会话中将为空,并且 session1 中的创建表将已提交,因为它是 mysql 上的隐式提交操作,在插入之前完成的任何操作也将被提交。这使您的 session2 在 版本表

中获取更新的值

索尔:

重新排序查询,以便在创建和插入的整个操作之后更新版本表。这将使您的系统可靠

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多