PHP队列执行任务的时候,如何防止进程之间抢夺资源?
phpcn_u747
phpcn_u747 2017-03-23 14:58:35
0
2
1248

PHP队列执行任务的时候,如何防止进程之间抢夺资源?
比如视频转码队列,每分钟会起一个进程去处理视频转码任务,每次从数据库获取10条
进程1已经获取了ID为10的视频去处理,一分钟后,如何防止进程2 拿到其他进程已经处理过的?
处理完成后,有异步通知,但是异步通知会有延迟,所以视频状态有可能修改不及时

phpcn_u747
phpcn_u747

reply all(2)
数据分析师

When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A - When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A

Come and watch and learn.

阿神

实际上有一个非常简单的办法,你可以利用数据库操作的原子性来实现,不需要那么复杂的锁机制,甚至队列。就按你的方法来,假设任务数据表 task 里有两个字段 id, status,我们定义status三个状态

0: 待处理
1: 正在处理
2: 处理完成

假设你有一堆 PHP 进程都用如下 SQL 语句去取出数据库里的待处理任务

SELECT * FROM task WHERE status = 0

取出来以后,我们为了防止其他用户不再重复取出要把它的状态标记为 1

UPDATE task SET status = 1 WHERE id = xxx

但是等等,这样就会产生如你所说的资源抢夺,但如果加上一个简单的技巧就可以避免,你把语句变成这样

UPDATE task SET status = 1 WHERE id = xxx AND status = 0

熟悉一点数据库的人可能会说这样还是避免不了抢夺,只是避免了重复写入。
我要说的是,能避免重复写入就够了,我们的进程在执行完这条操作后,去获取 affected_rows ,即更新的条数,根据数据库的原子性,只有第一个抢占的进程才会返回 1,它可以进行后面的操作。而剩下返回 0 的进程,直接进入下一个等待流程即可。

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template