我有以下设置:
如下的查询:
"INSERT INTO table (c1, c2,...) values (v01, v02,...), (v11, v12,...)..."
该表有一个带自动增量的主键。我需要知道每行插入的索引是什么。
执行此操作的一种方法是获取最后一行索引,插入的索引来自lastRowIndex - nrRows到lastRowIndex。
我的问题/不确定性是:如果另一个插入与此插入并行运行在同一个表中(另一个用户调用相同的函数),是否有任何机会(无论多小)插入一个之前所述查询生成的行之间的行?再次......非常重要(原因很明显......它杀死了ID结构),这种情况不会发生,所以我需要确定。
或者无论出于什么原因,ids都不能连续的任何机会。
答案 0 :(得分:1)
假设有两个事务正在运行,每个事务都将行插入到一个带有
AUTO_INCREMENT
列的表中。一个事务使用插入1000行的INSERT ... SELECT
语句,另一个事务使用插入一行的简单INSERT
语句:Tx1: INSERT INTO t1 (c2) SELECT 1000 rows from another table ... Tx2: INSERT INTO t1 (c2) VALUES ('xxx');
InnoDB无法预先知道将从
SELECT
中INSERT
语句中的Tx1
检索多少行,并且它会一次分配一个自动增量值作为声明收益。使用保持在语句末尾的表级锁定,一次只能执行一个引用表t1的INSERT
语句,并且不会交错不同语句生成的自动增量数。Tx1
INSERT ... SELECT
语句生成的自动增量值将是连续的,INSERT
中Tx2
语句使用的(单个)自动增量值将是小于或大于用于Tx1
的所有内容,具体取决于首先执行的语句。只要SQL语句在从二进制日志重播时(在使用基于语句的复制时或在恢复方案中)以相同的顺序执行,结果将与{{1时的结果相同首先运行。{/ strong}因此,表级锁定一直持续到语句结束时使用自动增量安全
Tx1
语句用于基于语句的复制。但是,当多个事务同时执行insert语句时,这些锁限制了并发性和可伸缩性。