2

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;

次に、オフラインで、作業の実行を待機するループ内にあるPHPCLIプロセスのプールがあります。作業を照会するには、次の関数を実行します。

$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...FORUPDATE」機能の2つを試しました。完全なLOCKTABLEコマンドも試しました。それにもかかわらず、デーモン内の2つのプロセスが同じ行を要求するという問題があり、その理由を特定できません。いくつかの疑い-別々のCLIプロセスを実行すると、PHPのセマフォはderpモードになりますか?または、MySQLは、基になるテーブルデータを実際に更新するために時間を取っているので、この関数が終了した後も、SELECTクエリはしばらくの間古いデータを返しますか?

他のアイデアはありますか?

本当にありがとう!

4

2 に答える 2

1

GAH!これが、コピー/貼り付けが悪である理由です。ここに問題があります:

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

「2」を使用すると、2つのプロセスが同時にセマフォを取得できます。ありがとう、ルイH.!

于 2013-01-30T15:12:32.397 に答える
0

追加のフィールドを追加します...たとえば、uniqueID

1)uniqueIDを生成します..。

$uniqueID = uniqid();

2)1行を更新します。フィールドuniqueID=$uniqueIDを設定します

3)行が存在する場合はuniqueID = $ uniqueIDである1つの行を選択し、それ以外の場合はジョブを実行します->別のレコードをマーク/取得しようとします

4)ジョブが終了したら、uniqueID =$uniqueIDの行を削除します。

利益!:)

さらに、「endTime」= currentDateTime + N_Minutes(分-この行がロックされる時間)を設定し、endTime <now()のときにuniqueIDをクリアすることができます

于 2013-09-16T14:51:41.900 に答える