There is one script. It runs several times, often several instances of the script are executed at the same time. It is necessary for the script to take the line in which in_use = 0, put in_use = 1 to it, process it and set it back in_use = 0. Naturally, no other instance of the script should get the same string. That is, it does not work out that the same line is processed simultaneously.
Task:
- Lock the table so that no one can read and write from it, in general
- Select a row from this table, and set this field to in_use = 1, set the lock flag
- Unlock
Tried to do a WRITE lock, but other threads can read the table. I made a READ lock, then I cannot write to the table. How to do both - I do not know.
PS There is a table for example tasks. Each copy of the script should take a free task, mark what it took, process it, and remove all locks. And at the moment when the script takes the task, no other should overtake him. That is, at the moment of SELECT, it is necessary that other processes wait for UNLOCK TABLES
$pdo->exec('LOCK TABLES links WRITE'); $sql = " SELECT hash FROM links WHERE in_use!=1 AND site=:site AND ( parsed is null OR DATEDIFF(CURDATE(),parsed)>=:revisit ) LIMIT 1 FOR UPDATE "; $statement = $pdo->prepare($sql); $statement->execute( [ ':site' => $site['name'], ':revisit' => static::$revisit, ] ); if ($statement instanceof PDOStatement && $statement->rowCount() == 1) { $hash = $statement->fetchAll(); $hash = $hash[0]['hash']; $pdo->exec("UPDATE links set in_use=1 where hash='" . $hash . "'"); } else { $hash = false; } $pdo->exec('UNLOCK TABLES'); return $hash; The code reads from the table Primari Key, puts the line in_use = 1. In another method, it is processed and after that put in_use = 0