在MySQL InnoDB中的事务期间锁定

时间:2016-06-15 00:36:33

标签: mysql transactions locking innodb acid

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

我有一个会话更新了最新版本"在版本表中,然后为新版本的几GB数据创建一个新表。另一个会话始终抓住最新版本,然后抓取最新版本的数据;我发现这个会话有时会返回0行数据。

这是SQL中的简化示例:

第1节

假设我们已经有一个表data_v41latest_version中的version_table为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数据后,是否需要在会话1中重新安排我的查询以更新版本?

1 个答案:

答案 0 :(得分:0)

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

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

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

中获取更新的值

Sol:

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