1

我有以下设置:

像这样的查询:

  "INSERT INTO table (c1, c2,...) values (v01, v02,...), (v11, v12,...)..."

该表有一个自动递增的主键。我需要知道插入的每一行的索引是什么。

一种方法是获取最后一行索引,插入的索引从 lastRowIndex - nrRows 到 lastRowIndex。

我的问题/不确定性是:如果另一个插入与在同一个表中插入行的插入并行运行(例如另一个用户调用相同的函数),是否有机会(无论多么小)在这些之间插入一行由前面所述的查询生成?再次......非常重要(原因很清楚......它会杀死 ids 结构)这不会发生,所以我需要确定。

或者无论出于何种原因,id 都不连续的任何机会。

4

1 回答 1

1

假设有两个事务正在运行,每个事务都将行插入到具有一AUTO_INCREMENT列的表中。一个事务使用INSERT ... SELECT插入 1000 行的语句,另一个事务使用插入一行的简单INSERT语句:

Tx1: INSERT INTO t1 (c2) SELECT 1000 rows from another table ...
Tx2: INSERT INTO t1 (c2) VALUES ('xxx');

InnoDB 无法预先知道将从SELECTinINSERT语句中的 检索多少行Tx1,并且随着语句的进行,它一次分配一个自动增量值。使用表级锁,保持到语句的末尾,一次只能INSERT执行一个引用表 t1 的语句,并且不同语句生成自增数不会交错。该语句生成的自动增量值将是连续的,并且该语句Tx1 INSERT ... SELECT使用的(单个)自动增量值将小于或大于所有用于 的自动增量值,具体取决于哪个语句首先执行。INSERTTx2Tx1

只要 SQL 语句在从二进制日志重放时(使用基于语句的复制时,或在恢复场景中)以相同的顺序执行,结果将Tx1Tx2第一次运行时相同。因此,表级锁一直保持到语句结束,使得INSERT使用自动增量的语句可以安全地用于基于语句的复制。但是,当多个事务同时执行插入语句时,这些锁会限制并发性和可伸缩性。

参考

于 2013-03-15T13:39:00.333 回答