前言
我们的应用程序运行多个DELETE
并行执行查询的线程。查询影响孤立的数据,即不应该存在并发DELETE
发生在来自不同线程的相同行上的可能性。但是,根据文档,MySQL 对DELETE
语句使用所谓的“next-key”锁,它同时锁定匹配的键和一些间隙。这会导致死锁,我们找到的唯一解决方案是使用READ COMMITTED
隔离级别。
问题
DELETE
使用JOIN
大表执行复杂语句时会出现问题。在特定情况下,我们有一个带有警告的表,只有两行,但查询需要从两个单独的INNER JOIN
ed 表中删除属于某些特定实体的所有警告。查询如下:
DELETE pw
FROM proc_warnings pw
INNER JOIN day_position dp
ON dp.transaction_id = pw.transaction_id
INNER JOIN ivehicle_days vd
ON vd.id = dp.ivehicle_day_id
WHERE vd.ivehicle_id=? AND dp.dirty_data=1
Run Code Online (Sandbox Code Playgroud)
当 day_position 表足够大时(在我的测试用例中有 1448 行),那么即使使用READ COMMITTED
隔离模式,任何事务也会阻塞整个 proc_warnings
表。
该问题始终在此示例数据上重现 - http://yadi.sk/d/QDuwBtpW1BxB9在 MySQL 5.1(在 5.1.59 上检查)和 MySQL 5.5(在 MySQL 5.5.24 上检查)中。
编辑:链接的示例数据还包含查询表的架构和索引,为方便起见,在此处复制:
CREATE TABLE `proc_warnings` (
`id` int(11) NOT NULL AUTO_INCREMENT, …
Run Code Online (Sandbox Code Playgroud)