php - PHP/MySQL 中的任务队列 : 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=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 查询仍会在短时间内返回旧数据?

还有其他想法吗?

非常感谢!

最佳答案

啊!这就是为什么复制/粘贴是邪恶的。问题是:

$seg = sem_get( $SEMKey, 2, 0666, -1) ; 

“2”允许两个进程同时获取信号量。谢谢,路易斯 H.!

关于php - PHP/MySQL 中的任务队列 : Race Condition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14606959/

相关文章:

php - mysql_data_seek 和 mysql_num_rows

python - 在多个不同的工作人员之间共享排队的工作负载

mysql - 从sql文件中导出一些表

php - 在 php 类中使用 phpmailer nameclass

php - 即使配置产品被禁用,Magento 也会从简单产品中获取可配置产品

php - 网站的搜索引擎

MySQL - 根据一列中的重复项满足另一列中的要求进行选择

java - Java有可索引的多队列线程池吗?

没有数据库查询的 laravel 队列

php - 无法与主机 smtp.gmail.com 建立连接 [操作超时 #60]