PHP/MySQL中的任务队列:竞争条件
我正在用PHP实现一个脱机任务队列。联机页在此表中插入记录以安排工作:PHP/MySQL中的任务队列:竞争条件,php,mysql,queue,conditional-statements,race-condition,Php,Mysql,Queue,Conditional Statements,Race Condition,我正在用PHP实现一个脱机任务队列。联机页在此表中插入记录以安排工作: create table sl_task_queue ( task_id int primary key auto_increment, task_data varchar(255) not null, started_date datetime, completed_date datetime, priority int not null default 10 ) ENGINE=In
create table sl_task_queue (
task_id int primary key auto_increment,
task_data varchar(255) not null,
started_date datetime,
completed_date datetime,
priority int not null default 10
) ENGINE=Innodb;
然后,离线时,我有一个PHP CLI进程池,它们处于循环中,等待工作完成。要查询工作,他们运行以下功能:
$SEMKey = "849039";
$seg = sem_get( $SEMKey, 2, 0666, -1) ;
function getTask() {
sem_acquire($GLOBALS['seg']);
// This function returns null for no results, or a Task ORM object on success
$Task = eSqlObject("Task", "select * from sl_task_queue
where started_date is null
order by task_id asc limit 1 for update");
if( $Task ) {
// Set started_date to claim this task
$Task = new LucidityTask($hash);
$Task['started_date'] = date("Ymd H:i:s");
$Task->save(); // performs an UPDATE query
}
sem_release($GLOBALS['seg']);
return $Task;
}
我在这里尝试了两件事,一个PHP信号和MySQL的“选择…更新”特性。我还尝试了一个完全锁表命令。尽管如此,守护进程中声明同一行的两个进程仍然存在问题,我无法确定原因。有两个疑问-当您执行单独的CLI进程时,PHP的信号量是否会进入derp模式?或者MySQL真的花了很多时间来更新底层表数据,这样在这个函数退出后,SELECT查询仍然会在短时间内返回旧数据吗
还有其他想法吗
非常感谢 GAH!这就是为什么复制/粘贴是邪恶的。问题是:
$seg = sem_get( $SEMKey, 2, 0666, -1) ;
“2”允许两个进程同时获取信号量。谢谢你,路易斯·H 添加其他字段…例如uniqueID 1) 生成唯一ID
$uniqueID = uniqid();
2) 更新一行。设置字段uniqueID=$uniqueID
3) 选择一行,其中uniqueID=$uniqueID
如果行存在->执行作业其他->尝试标记/获取另一条记录
4) 删除作业完成时uniqueID=$uniqueID的行
利润!:)
此外,您还可以设置“endTime”=currentDateTime+N_分钟(分钟-此行将被锁定的时间)
当endTime