【问题标题】:Handling innoDB deadlock处理 innoDB 死锁
【发布时间】:2011-07-15 21:25:45
【问题描述】:

我的 InnoDB 表出现Deadlock found when trying to get lock; try restarting transaction 错误。这是查询:

UPDATE views 
SET visit_cnt = visit_cnt + 1 
WHERE visit_day = DATE(NOW()) 
AND article_id = '4838'

此查询也通过 ON UPDATE 触发器触发:

UPDATE articles 
SET views = views + 1 
WHERE id = NEW.article.id

这是我尝试修复它的方法:

$attempts_left = 5;
do
{
    mysql_query ($query);

    // if we found a deadlock, we will try this query 4 more times   
    if (mysql_errno () == 1213) { // 1213 - deadlock error
        $deadlocked = true;
        $attempts_left --;
    }
    else{
        $deadlocked = false;
    }
}
while($deadlocked && $attempts_left > 0);

我的问题:这是处理死锁的唯一方法吗?我的意思是这很丑陋,无论如何都会时不时发生死锁。有没有推荐的方法来解决死锁?

【问题讨论】:

标签: php mysql innodb deadlock


【解决方案1】:

这是关于处理 InnoDB deadlocks 的好文档。

PS:我没有什么要补充的,所以把链接给你了。

【讨论】:

  • 谢谢,我在 MySQL 网站上放松了说明。命令 SHOW ENGINE INNODB STATUS 给出了导致所有锁定问题的大查询。
【解决方案2】:

您可能需要使用事务隔离/MVCC 功能玩一些游戏

选项 1) 您可能希望将查询包含在开始提交块中

BEGIN;

UPDATE views
SET visit_cnt = visit_cnt + 1
WHERE visit_day = DATE(NOW())
AND article_id = '4838';

< Any actions in the trigger would be part of the transaction >

COMMIT;

选项 2) 您可能希望为您的会话禁用自动提交

SET autocommit = 0;

选项 3)在启动查询之前更改事务隔离以公开脏读

这是一个延伸!!!

SET tx_isolation = READ_COMMITTED;

SET tx_isolation = READ_UNCOMMITTED;

试一试,让我们都知道!!!

【讨论】:

    【解决方案3】:

    这是正确的方法,正如文档所述:

    通常,您必须编写应用程序,以便它们随时准备好在事务因死锁而回滚时重新发出事务。

    如果你想减少死锁的发生,你必须向我们展示表 DDL 和索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      • 2021-10-27
      相关资源
      最近更新 更多