Laravel工作器失败,原因是JOBS表上的死锁导致SQLSTATE [HY000]:常规错误:1205超出了锁定等待超时

问题描述

问题-

删除作业条目时,由于在JOBS表上造成死锁,我的工作人员失败了。

这种行为是经常发生的,即使流量略有增加

需要避免这种死锁的建议吗?

配置-

  • 使用Laravel队列和QUEUE_DRIVER = database

  • 主管作为队列管理器

  • 数据库MysqL

日志-

{"message":"sqlSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; 
try restarting transaction (sql: delete from `jobs` where `id` = 215520)","context":{"exception":{"class":"Illuminate\\Database\\QueryException","message":"sqlSTATE[40001]: 
Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction 
(sql: delete from `jobs` where `id` = 
215520)","code":40001,"file":"/home/aditya/Desktop/code/Chqbook-
api/vendor/laravel/framework/src/Illuminate/Database/Connection.PHP:664","prevIoUs":
{"class":"PDOException","message":"sqlSTATE[40001]: Serialization failure: 1213 Deadlock found 
when trying to get lock; try restarting 
transaction","file":"/home/aditya/Desktop/code/Chqbook-
api/vendor/laravel/framework/src/Illuminate/Database/Connection.PHP:483"}}},"level":400,"level_n
ame":"ERROR","channel":"local","datetime":{"date":"2020-09-17 
07:22:56.546154","timezone_type":3,"timezone":"Asia/Kolkata"},"extra":[]}

{"message":"sqlSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction (sql: insert into `jobs` (`queue`,`attempts`,

解决方法

Taylor Otwell承认mysql从未打算用于队列。遇到此问题的原因可能有很多。

也许您应该考虑在队列中使用Redis而不是mysql(为什么不使用Horizo​​n呢?

,

死锁和锁定等待超时是相关的问题。

您有2个(或更多)连接,它们正在与同一张表的相同(或相邻)行做某事。

MySQL可能会采取两项措施:

  • 停止一个连接,直到另一个释放行。如果释放花费的时间太长,则等待的连接将放弃“等待锁定超时”。故事的寓意:不要写花费超过几秒钟才能完成的事务:
  • 如果每个人都在等待对方,则可能会出现“死锁”。一个连接的事务中止。使查询更快可以减少死锁的频率。准备重新执行事务是处理死锁的最终方法。

使用MySQL作为队列管理器会诱使您

  1. 从队列中获取项目
  2. 处理
  3. 从查询中删除项目

在事务中执行所有这三个步骤是合乎逻辑的。但是,如果步骤2花费了“很长时间”,则您正在乞求上面列出的问题之一。

更好的方法是:

BEGIN  
1. Grab an item from the queue
2. Mark it as taken
COMMIT  

3. Process it at your leisure

BEGIN
4. Remove the item from the queue
COMMIT