mysql - Mysql发现死锁

标签 mysql stored-procedures

我有两个程序,其中一个程序通过从 3 个不同的表中选择和计算这些值来更新表中的列,并且该程序每 1 分钟运行一次 (24 X 7)。

另一个过程,通过从上述 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”条件。

请指教。

谢谢

最佳答案

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

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

有关死锁的问题和解答有很多。每次插入/更新/或删除一行时,都会获取一个锁。为了避免死锁,您必须确保并发事务不会按照可能导致死锁的顺序更新行。一般来说,即使在不同的事务中,始终尝试以相同的顺序获取锁(例如,始终先表 A,然后表 B)。

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

Source

关于mysql - Mysql发现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21556089/

相关文章:

php - 获取合并的两个表(不显示想要的结果)

在while循环中工作的php jquery弹出消息框

mysql - 从mysql中的多个表中选择多列

sql-server - T-SQL 动态 SQL 和临时表

php - 检查存储过程是否仍在 Codeigniter 中运行

php - 存储过程中的 SQL 查询与从 PHP 执行的 SQL 有何不同?

php - 使用php导出的csv文件格式出现错误

mysql - 连接表查询慢

MySQL COUNT 子查询与 SELECT *

php - SQLSRV 和存储过程中的多项选择