I have a PHP script (deleteAndReInsert.php) that deletes all rows where name = 'Bob', and then inserts 1000 new rows with name = 'Bob'. This works correctly, and the initially empty table ends up with 1000 total rows as expected.
$query = $pdo->prepare("DELETE FROM table WHERE name=?");
$query->execute(['Bob']);
$query = $pdo->prepare("INSERT INTO table (name, age) VALUES (?,?)");
for ($i = 0; $i < 1000; $i++)
{
$query->execute([ 'name' => 'Bob', 'age' => 34 ]);
}
The problem is if I run deleteAndReInsert.php twice (almost at the exact same time), The final table contains more than 1000 rows.
What seems to be happening is that the DELETE query from the first run finishes, and then many (but not all) of the 1000 INSERTS get called.
Then the second DELETE query starts and finishes before the first 1000 INSERTS finishes (say 350 of the 1000 INSERTS complete). Now the second 1000 INSERTS runs, and we end up with 1650 total rows instead of 1000 total rows because there are still 1000 - 350 = 650 INSERTS remaining after the second DELETE gets called.
What's the correct way to prevent this problem from happening? Should I wrap everything in a transaction, or should I make 1 batch insert call instead of 1000 individual inserts? Obviously I can implement both of these solutions, but I'm curious as to which one is guaranteed to prevent this problem.