两个队列任务同时操作一张表导致锁表,任务失败,请问如何解决?
两个队列任务同时操作一张表导致锁表,任务失败,请问如何解决?
Redis队列两个任务有几率同时更新一张表数据,导致报错Deadlock found when trying to get lock;try restarting transaction
应该是两个相同任务,同时执行,操作了同一个表,导致的,是我修复逻辑不让他们通知操作一张表,还是有办法,让他们可以同时操作同一张表?
// 下面这段代码按照条件筛选出的数据更新外键
// 操作表 collect_data
$collect->where('keywords', '=', $goods_item['keywords'])
->where('title', 'not like', '拍拍 %') // *** 搜索条件并非空格,是特殊字符(全角空格?) ***
->where($orWhereBrand)
->where($orWhereSKU)
->where($whereFilter)
->where($whereBlock)
->where($orWhereShop)
->where($whereShopBlock)
->update(['goods_uuid' => $goods_item['uuid']]);
// 下面这段代码是更新主表商品状态,如果关联字表价格低于主表商品,商品状态更新为2 否则3
// 主表 goods 子表 collect_data
$update_sql = 'UPDATE ' . $goods_table . ' AS goods
INNER JOIN (SELECT goods_uuid, MIN(price) price FROM ' . $collect_table . ' GROUP BY goods_uuid) AS collect_data
ON goods.uuid = collect_data.goods_uuid
SET goods.is_warning = IF(collect_data.price < goods.price, 2, 3)
WHERE collect_data.goods_uuid = "' . $goods_item['uuid'] . '"';
DB::update($update_sql);
发生这种情况可能是一个事务未提交(mysql默认是开启自动提交事务的),另一个事务已经提交。导致的锁表或者锁行。
可以手动加锁,上一条未执行完毕,后面的需要等待。
可以使用redis加锁,然后队列中锁住的条件进行重试。条件用查询的唯一条件拼接。
这是之前参考论坛里大佬写的 service 你也可以参考一下。