mysql - 从 MySQL 5.5 InnoDB 中的选择查询插入

标签 mysql concurrency

我有一个疑问。

INSERT INTO users_resources_locks (resource_id, user_id)
SELECT resources.id, 123 FROM resources
LEFT JOIN users_resources_locks
    ON resources.id = users_resources_locks.resource_id
WHERE users_resources_locks.id IS NULL;

表users_resources_locks在列resource_id上​​有唯一索引。

并发查询是否可以在查询的 INSERT 和 SELECT 部分之间写入 users_resources_locks?

例如,在可重复读隔离级别中,下面的时间线是否可能?

1) My query selects ((1, 123), (2, 123), (3, 123)).
2) Concurent query writes into users_resources_locks values ((1, 54321), (2, 54321)) and commits trasaction.
3) My query writes into users_resources_locks values ((1, 123), (2, 123), (3, 123)) and commits transaction fails because of unique constraint.

最佳答案

不,据我所知,像 INSERT 这样的 DML 语句需要独占记录级隐式锁,因此当一个插入正在进行时,另一个 INSERT/UPDATE 无法执行通过。它取决于读取器/写入器锁以及数据库引擎对锁兼容性的检查。

Read Lock - R
Write Lock - W

有了这个,RW/WR/RR 都是兼容的锁,因为读取需要共享锁(同样取决于 TRANSACTION ISOLATION LEVEL),但是 WW 始终是不兼容的锁。

此外,如果您的 ID 列是主键或任何键列(例如唯一键),那么它就不可能重复。

关于mysql - 从 MySQL 5.5 InnoDB 中的选择查询插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32446253/

相关文章:

mysql - 将数据添加到相互关联的表..更简单的方法?

mysql - mysql 中的数据类型大小和存储

.NET 客户端并发性能

c# - 为什么 Parallel.For 对这个特定函数的增益如此之小?

java - 执行超时后返回的长时间计算

java - 是否可以使可序列化类的锁暂时存在?

Java ConcurrentSkipListMap 卡在某些线程中

mysql - Mnesia 中的唯一约束

javascript - *ngFor 需要为每个不同的对象生成 1 个 btn,但将相似的对象值放在同一个 btn 中

mysql - 如何从同一个表中的主键和外键的mysql表中删除主键。?