假设我有一个表单查询:
INSERT INTO tableA (...) select ... from tableB;
现在,这个查询是否有可能在执行时阻止普通INSERT
语句tableB
?附加信息:
- 所有表都是 InnoDB
- 没有显式事务(自动提交已打开)
- 语句中没有
FOR UPDATE
子句SELECT
(我什至不确定是否可以在INSERT...SELECT
构造中做到这一点) - 实际的 SELECT 查询显然更复杂,涉及分组和联合,但这些不应该改变任何东西,对吧?
- 所有查询的事务隔离级别是默认的
REPEATABLE READ
- 准确的数据库版本是 MariaDB 10.0.12
是的,
SELECT
在这种情况下是锁定选择。如果您
SELECT
在任何更改数据的查询中使用,则它隐含地是一个锁定查询,就像您使用过SELECT ... LOCK IN SHARE MODE
. 这会在它读取的行上放置一个共享锁。任何其他更改数据的语句的行为方式相同。这包括以下情况:
INSERT ... SELECT ...
CREATE TABLE ... AS SELECT ...
SELECT ... INTO variable
或者... INTO OUTFILE
SET @variable = (SELECT ...)
INSERT
//在其主体UPDATE
中DELETE
运行 a的触发器。SELECT
UPDATE
orDELETE
语句中的子查询一个共享锁可能被多个并发会话持有。因此,您可以
INSERT ... SELECT
在多个事务中执行此查询。他们不会互相冲突。但是一个
INSERT
to tableB 必须有一个排他锁。如果存在任何共享锁,则不会授予排他锁。