【问题标题】:mysql insert...select statement causing deadlock in concurrent requestmysql insert...select语句导致并发请求死锁
【发布时间】:2017-08-30 11:17:57
【问题描述】:

MySQL 5.7 版 引擎:InnoDB

我有一个名为“md_waiting_slot_count”的表,它有以下列:

cell | popupDate | userId | creationTime

现在我有以下查询:

insert into md_waiting_slot_count 
select cell, '2017-08-31' as pd, 'abnc' as ui, '2017-08-26 15:55:51'  
from 
(select sum(slotcount) as tt, cell from 
( select 0 as slotcount, cell_str as cell, 'master' from cell where 
cell_str in 
("Gujarat_Jamnagar_Jamnagar_00-18_Male","Gujarat_Jamnagar_Jamnagar_19-
22_Male")  

union all  

select slotcount, cell, wting from
(select count(*) as slotcount, cell as cell, 'waiting' as wting from 
md_waiting_slot_count where 
cell in(SELECT cell_str as cell FROM cell where cell_str 
in("Gujarat_Jamnagar_Jamnagar_00-18_Male","Gujarat_Jamnagar_Jamnagar_19-
22_Male")) 
and popupDate='2017-08-31' and creationTime > DATE_SUB(NOW(), INTERVAL 
20 MINUTE) group by cell ) as t1

union all  

select filledslotcount as slotcount, id as cell, 'final' from 
md_slot_count where id in(
SELECT cell_str as cell FROM cell where cell_str 
in("Gujarat_Jamnagar_Jamnagar_00-18_Male","Gujarat_Jamnagar_Jamnagar_19-
22_Male")) 
and popupSlotDate='2017-08-31' ) t group by cell having tt < 4) as ft 
order by cell, pd, ui
on duplicate key update creationTime = "'2017-08-26 15:55:51'";

这里还用到了另外两个表,如下

md_slot_count id| popupDate| state| district| taluka| ageGroup| gender| filledSlotCount

cell cell_str| state| district| taluka| ageGroup| gender

这个 insert...select 语句在 3-4 成功运行后导致死锁。

帮我解决这个问题。 如何在 MySQL 中查看“最后一个死锁日志”?

我想做这样的事情

事务 1 --> 评估上面的查询 --> 插入行

事务 2 --> 评估上述查询 --> 插入行

在这里,当第二个事务评估查询时,它必须考虑前一个事务插入的数据。在这里,我想允许最多 4 个事务插入行,仅此而已。所以评估的查询允许插入然后只插入。

现在并行请求,如果查询评估和插入这两个过程是分开的并且不考虑以前的事务数据,那么可以有超过 4 个事务来插入数据。

所以最终目标是

如果一个事务开始并读取数据并满足条件然后插入数据并意味着没有其他人进行插入,并且当第一个事务完成时,第二个事务必须只考虑所有更新的数据。因此,一个事务要么完成要么什么都没有,而其他事务必须等待。 我没有在并发请求中实现,因为所有人一起读取,所以它读取旧数据,所以所有人都可以在表中添加数据。 所以我把这整个放在一个查询中。

【问题讨论】:

  • 您正在插入md_waiting_slot_count,同时在插入过程中还从该表中进行选择。除此之外,有时您会更新此表。我的猜测是这种结构是死锁的根源。有什么办法可以避免以这种方式插入?
  • 你是第 1 列所有不同数量和类型的联合:选择单元格,'2017-08-31' 作为 pd,'abnc' 作为 ui,'2017-08-26 15:55:51 ' 2: select slotcount, cell, wt.. 确保这个查询有效??????
  • @Tim Biegeleisen 我这样做是因为,我只想在选择查询评估成功并返回行时才插入,否则不会。如果这些是 2 个单独的查询,那么在并发请求中它会插入超过 4 行,我在上面的查询中的有子句中提到了这些行。这个单独的语句在并发请求中不起作用。
  • @scaisEdge 是的,这个查询工作正常。
  • @DhavalBhoot 尝试改写查询,这样您就不需要在插入期间从同一个表中进行选择。这是我要尝试的第一件事。

标签: mysql select insert database-deadlocks


【解决方案1】:

您想将一些从 md_waiting_slot_count 计算的数据插入到 md_waiting_slot_count 中。 所以死锁在所难免。尝试创建一个包含您的值的临时表,然后从您的临时表中插入您的值。

【讨论】:

  • 我无法在另一个临时表中插入数据,因为我想在下面的选择查询中使用其他下一个事务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
  • 2010-12-03
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多