I'm on MariaDB 10.6.5, and I have this code :
$pdo->query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;");
$pdo->query("SET autocommit = 0;");
try
{
$max_id = $pdo->query("SELECT MAX(id) FROM test")->fetchColumn();
sleep(3);
$insert_sql = $pdo->prepare("INSERT INTO test(test) VALUES(:test)");
$insert_sql->execute(['test' => $max_id 1]);
}
catch (Throwable $e)
{
$pdo->query("ROLLBACK;");
}
$pdo->query("COMMIT;");
The test table has two columns : id (auto incremented) & test (int).
When two users execute this code at the same time, I want the first transaction to lock the test table at the SELECT statement and for the second transaction to wait at the SELECT statement for the first one to finish.
If everything goes well, the id column should always be equal to the test column.
Is this possible ? And if so, how ?
For clarification, here's what I want to happen :
- Two users
U1andU2run this code at the same time,U1runs it a few microseconds earlier U1runs theSELECTstatement, locking the tabletestU1runs theINSERTstatementU1runs theCOMMITstatement, unlocking the tabletestU2runs theSELECTstatement, reading the newMAX(id)after theINSERTofU1U2runs theINSERTstatementU2runs theCOMMITstatement
CodePudding user response:
You can use GET_LOCK
add the query DO GET_LOCK('lockname', 30) at the start and DO RELEASE_LOCK('lockname') after the query.
So when User 1 starts the query it sets the lock lockname and only releases it when finished, If User 2 starts the script DO GET_LOCK('lockname', 30) waits for the lock to be released before continuing.
