我用的是Laravel 5.1。
队列用于多个系统之间的数据获取/同步。
我使用的是数据库驱动程序,3个“artisan queue:work --daemon”进程一直在运行。
作业由系统用户和调度程序(cron)调度。使用三个队列来确定作业的优先级。
一切似乎都运行得很好--作业表中充满了记录,系统会处理它们并删除已完成的记录。
然而,一段时间后,锁定问题开始干扰:
SQLSTATE[40001]:序列化失败:1213尝试获取锁时发现死锁;尝试重新启动事务
和
“RuntimeException”,消息为“在事务内无法交换PDO示例”。
和
SQLSTATE[HY000]:一般错误:1205锁定等待超时;尝试重新启动事务
我还没有尝试使用其他队列驱动程序。我真的很喜欢数据库。引擎是InnoDB,作业表具有默认结构和索引。
有没有办法解决这个问题?你的想法是什么?
值得一提的是,我在作业类中调用了DB::reconnect()
,因为队列工作进程是作为守护进程运行的。
正如人们所期望的那样,使用DispatchesJobs
trait分派作业。我不会以任何其他方式干扰队列算法。
3条答案
按热度按时间ssm49v7z1#
这可能不是答案,而是一些信息。
当使用
SELECT ... FOR UPDATE
语句时,您可能会观察到锁争用(死锁等)。它是使用<=进行范围扫描,数据库锁定所有行<= y,包括任何间隙,因此如果您有如下所示的带有y的行:1,3,5它甚至锁定索引中1和3之间的空白空间,这称为间隙锁定
可以看到此命令的问题:
末行
如果你的事务中有很多影响并发和性能的间隙锁,你可以用两种不同的方法禁用它们:
https://www.percona.com/blog/2012/03/27/innodbs-gap-locks/
deikduxw2#
我在Laravel上写队列管理系统,我有多个工作,有多个用户,我应该发送电子邮件。我运行许多工人与主管,以避免多个电子邮件发送给同一个用户,我写了这段代码。希望它能帮助解决这个问题的人
j2qf4p5b3#
在管理程序配置文件中,使numprocs = 1,因为“205锁定等待超时已超过;尝试重新启动”此错误只发生在多个队列工作者在同一表或表的同一行上执行同一任务时。这将在表中创建死锁