问题-
我有失败的工人,因为在删除作业的条目时,JOBS表出现死锁。
这种行为经常发生,即使交通量略有增加。
需要避免这种僵局的建议吗
配置-
-
使用Laravel队列和QUEUE_DRIVER=数据库
-
主管作为队列管理器
-
DB是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","code":40001,"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`,
死锁和锁等待超时是相关的问题。
您有两个(或多个(连接正在对同一表的同一(或相邻(行执行某些操作。
MySQL可能会采取两种操作:
- 暂停一个连接,直到另一个连接释放行。如果释放需要";太";长,等待的连接放弃";等待锁定超时";。故事的寓意:不要写需要几秒钟以上才能完成的交易:
- 如果每个人都在等待另一个人,那么你就有了一个"等待";死锁";。一个连接的事务已中止。加快查询速度可以降低死锁的频率。准备好重新执行事务是处理死锁的最终方法
使用MySQL作为队列管理器会诱使您使用
- 从队列中获取项目
- 处理它
- 从查询中删除项目
在事务中执行所有这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
Taylor Otwell承认mysql从未用于队列:https://github.com/laravel/framework/issues/15192#issuecomment-你面临这个问题的原因有很多。
也许你应该考虑使用Redis而不是mysql来处理你的队列(为什么不使用Horizon呢,这太神奇了(