在Mysql中找到死锁

时间:2014-02-04 15:09:27

标签: mysql stored-procedures

我有两个程序,一个是 UPDATE '表中的一个列,通过从3个不同的表中选择和计算这些值,此程序每1分钟运行一次(24 X 7)。

另一个过程, INSERT 通过从上面提到的3个表中的一个表中选择数据将结果放入新表中,并且此过程每天早上运行一次。

问题是当两个程序碰巧在早上同一时间运行时,发现一个死锁,而其中一个事务正在锁定特定键。

如何避免这种情况?

update 
table1 as p
right join table2 as a on a.col = p.col
left join table3 as b on a.col = b.col 
and b.date = (select min(tdate) from  table3  where  tdate between date(concat(year(current_date - interval 1 year), '-12-31')) and(current_date) and col = a.col for update)
left join table4 c on a.col = c.col
left join (select col, ifnull(sum(col1), 0) amt from table5 where rdate between date(concat(year(current_date - interval 1 year), '-12-31')) and (current_date) group by col for update) d 
on a.ticker = d.ticker
set  p.col1 = ((round(ifnull(d.amt,0),2) + c.val - b.val) / b.val) * 100


insert into new_table (col1,col2,tr_date)  
select sm.col,s.val,s.tr_date 
from 
table3 as s,
table2 as sm 
where 
sm.col=s.col and
s.val = (select max(val) from table3 as  q where q.tr_date between (current_date-interval 1 year) and (current_date) and q.col =sm.col) 
group by sm.col,s.val

这是我正在使用的两笔交易,

“table3”是在两个交易中使用的那个,并且两者都使用“where”条件。

请告知。

由于

1 个答案:

答案 0 :(得分:1)

当两个事务相互等待获取锁定时发生死锁。示例:

  • Tx 1:锁定A,然后是B
  • Tx 2:锁定B,然后是A

有很多关于死锁的问题和答案。每次插入/更新/删除行时,都会获取锁定。为避免死锁,您必须确保并发事务不会按顺序更新行,从而导致死锁。一般来说,即使在不同的交易中,也会尝试以相同的顺序获取锁定(例如,首先是表A,然后是表B)。

数据库死锁的另一个原因可能是缺少索引。插入/更新/删除行时,数据库需要检查关系约束,即确保关系一致。为此,数据库需要检查相关表中的外键。 可能导致获取其他锁定而不是修改的行。确保总是在外键(当然还有主键)上有索引,否则可能导致表锁而不是行锁。如果发生表锁定,则锁争用会更高,并且死锁的可能性会增加。

Source