【问题标题】:Lock wait timeout when Laravel worker processes job batchesLaravel worker 处理作业批次时锁定等待超时
【发布时间】:2022-02-16 20:00:50
【问题描述】:

我在日志中看到以下错误。

SQLSTATE[HY000]:一般错误:1205 超过锁定等待超时;尝试 重新启动事务(SQL:select * from job_batches where id = xxx限制1更新)

我发现这个查询是在 Laravel 更新数据库中已处理作业的数量之前进行的。但是不知道为什么会发生这种超时(代码在事务内部,所以应该立即释放锁)。

附:我使用 Amazon SQS 来驱动我的队列

附言我建议有些工作没有提交嵌套的 Laravel 事务。但是我尝试重现这样的场景,看来这个建议是错误的。

【问题讨论】:

标签: php mysql laravel amazon-sqs


【解决方案1】:

简而言之,这是因为一批工作量很大。解决方案是将作业以较小的块添加到批处理中(使用add() 方法)。

问题出现是因为在一个事务中发生了两件事(见下面的代码片段):

  1. 数据库中的作业总数已更新
  2. 作业被发送到队列(在我的例子中是 Amazon SQS)

关键是如果有很多工作,第二个语句会花费很多时间。并且只要执行事务就不能提交(并且第一条语句中受影响的行保持锁定)。 但是一旦第一个作业被推送到队列中,它就会被工作人员处理。在处理完作业工作者尝试更新数据库中的行后,它执行SELECT ... FOR UPDATE。等待超时发生

这是Laravel的代码对应片段:

$this->repository->transaction(function () use ($jobs, $count) {
    // Statement 1 (the affected row stays locked until transaction is committed)
    $this->repository->incrementTotalJobs($this->id, $count);

    // Statement 2 (can take a lot of time)
    $this->queue->connection($this->options['connection'] ?? null)->bulk(
        $jobs->all(),
        $data = '',
        $this->options['queue'] ?? null
    );
});

【讨论】:

    猜你喜欢
    • 2016-12-16
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 2017-02-01
    相关资源
    最近更新 更多