Php 避免MySQL在尝试获取锁时出现死锁;尝试重新启动事务'

Php 避免MySQL在尝试获取锁时出现死锁;尝试重新启动事务',php,mysql,deadlock,database-deadlocks,Php,Mysql,Deadlock,Database Deadlocks,我有时会收到mysql死锁错误,如: '尝试获取锁时发现死锁;尝试重新启动事务' 我有一个队列表,其中多个php进程同时运行,从表中选择行。但是,对于每个进程,我希望它在每次提取时都获取一批唯一的行,这样就不会选择任何重叠的行 所以我运行这个查询:这是我得到死锁错误的查询 $this->db->query("START TRANSACTION;"); $sql = " SELECT mailer_queue_id FROM

我有时会收到mysql死锁错误,如:

'尝试获取锁时发现死锁;尝试重新启动事务'

我有一个队列表,其中多个php进程同时运行,从表中选择行。但是,对于每个进程,我希望它在每次提取时都获取一批唯一的行,这样就不会选择任何重叠的行

所以我运行这个查询:这是我得到死锁错误的查询

    $this->db->query("START TRANSACTION;");

    $sql = "   SELECT   mailer_queue_id
                FROM    mailer_queues
                WHERE   process_id IS NULL
                LIMIT   250 
                FOR UPDATE;";
    ...


    $sql = "UPDATE  mailer_queues
            SET     process_id = 33044,
                    status = 'COMPLETED'
            WHERE   mailer_queue_id 
                IN  (1,2,3...);";

    ...

    if($this->db->affected_rows() > 0) {
        $this->db->query("COMMIT;");       
    } else{
        $this->db->query("ROLLBACK;");      
    }
我还:

向表中同时插入不带事务/锁的行

同时更新表中没有事务/锁的行

同时删除表中没有事务/锁的行

此外,我的更新和删除仅更新和删除分配了流程id的行…以及执行选择行的事务的行。。。对于更新,进程的id=null。理论上,它们不应该重叠

我想知道是否有一个适当的方法来避免这些僵局

是否会因为一个事务在选择/更新表时锁定表的时间太长,而另一个进程尝试执行同一个事务并超时而导致死锁


当两个或多个进程请求锁定时,会出现死锁,导致被锁定的资源重叠,但顺序不同,因此每个进程都在等待另一个进程锁定的资源,而另一个进程则在等待原始进程已打开的锁

在现实世界中,考虑一个建筑工地:你有一个螺丝起子和一个螺丝钉。两个工人需要拧一个螺丝。工人1抓住螺丝刀,工人2抓住螺钉。工人1也去抓螺丝,但不能,因为它被工人2抓住了。工人2需要螺丝刀,但无法获得,因为工人1拿着螺丝刀。所以现在他们陷入僵局,无法继续前进,因为他们拥有所需的两种资源中的一种,他们两人都不会有礼貌地退后一步


如果您没有进行事务更改,则可能有一个或多个更新/删除与您在事务中保留的锁定区域重叠。

当两个或多个进程请求锁定时,会发生死锁,锁定的资源重叠,但顺序不同,因此,每个进程都在等待另一个进程锁定的资源,而另一个进程则在等待原始进程已打开的锁

在现实世界中,考虑一个建筑工地:你有一个螺丝起子和一个螺丝钉。两个工人需要拧一个螺丝。工人1抓住螺丝刀,工人2抓住螺钉。工人1也去抓螺丝,但不能,因为它被工人2抓住了。工人2需要螺丝刀,但无法获得,因为工人1拿着螺丝刀。所以现在他们陷入僵局,无法继续前进,因为他们拥有所需的两种资源中的一种,他们两人都不会有礼貌地退后一步


考虑到您已经发生了事务外更改,您的一个或多个更新/删除可能与您在事务内保留的锁定区域重叠。

您可能希望在启动事务之前尝试锁定表,从而确保您对表有明确的控制权。锁定将等待特定表上的所有活动完成。

您可能希望在启动事务之前尝试锁定表,从而确保您对表具有明确的控制权。锁将等待特定表上的所有活动完成。

我认为网络上的每个人都对死锁进行了很好的解释。 Mysql提供了很好的日志来检查最近发生的所有死锁以及 当时查询被卡住了。 选中此项并搜索最新检测到的死锁
这是一个很棒的日志,帮助发现了许多微妙的死锁。

我想网络上的每个人都对死锁做了很好的解释。 Mysql提供了很好的日志来检查最近发生的所有死锁以及 当时查询被卡住了。 选中此项并搜索最新检测到的死锁
这是一个很好的日志,有助于找到许多微妙的死锁。

谢谢你的回答@Marc B。关于我的更新和删除,有趣的是我只更新和删除分配了进程id的行……而我执行选择更新行的事务的地方是进程id=null的地方。理论上,它们不应该重叠。谢谢你的回答@Marc B。关于我的更新和删除,有趣的是我只更新和删除分配了流程id的行……我执行选择更新行的事务的地方是流程id=nu的地方
陆上通信线。理论上,它们不应该重叠。您使用的是哪个MySQL存储引擎?InnoDB或MyISAM?您使用的是哪种MySQL存储引擎?InnoDB还是MyISAM?