我正在用 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=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 的“SELECT ... FOR UPDATE”功能。我还尝试了一个完整的 LOCK TABLE 命令。尽管如此,我仍然在守护进程中的两个进程声称同一行时遇到问题,我无法确定原因。几个怀疑 - 当您执行单独的 CLI 进程时,PHP 的信号量是否进入 derp 模式?或者 MySQL 是否在花时间实际更新基础表数据,以便在此函数退出后,SELECT 查询仍会在短时间内返回旧数据?
还有其他想法吗?
非常感谢!