mysql insert ... select语句在并发请求中导致死锁

时间:2017-08-30 11:17:58

标签: mysql select insert database-deadlocks

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次成功运行后导致死锁。

帮助我。 如何查看&#34;最后一个死锁日志&#34;在MySQL?

我想做这样的事情

  

交易1 - &gt;评估以上查询 - &gt;插入行

     

交易2 - &gt;评估以上查询 - &gt;插入行

这里当第二个事务评估查询时,它必须考虑先前事务插入的数据。在这里,我想允许max 4事务插入行,不多于此。因此,评估的查询允许插入然后只插入。

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

所以最终的目标是

  

如果一个事务开始并读取数据并满足条件,则在没有其他人插入时插入数据和平均值,并且当第一个事务完成时,第二个事务必须仅考虑所有更新的数据。因此,对于一个事务,其他事务必须等待完成或不完成。 我没有在并发请求中实现,因为它们一起读取所以它读取旧数据所以所有都能够在表中添加数据。   所以我将这一整体放在一个查询中。

1 个答案:

答案 0 :(得分:0)

您希望将从md_waiting_slot_count计算的一些数据插入md_waiting_slot_count。 所以僵局是不可避免的。尝试创建一个包含值的临时表,然后从临时表中插入值。