Let's say I have a script which inserts rows into the database and it looks like this:
/* $start is some GET parameter. Any number between 0 and 9900 */
/* Select all objects with ids between $start and $start+99
and put their ids into $ids array */
$qb->select('object');
$qb->from('AppBundle:Object','object');
$qb->where("object.id >= $start");
$qb->andWhere("object.id < $start+100");
$objects = $qb->getQuery()->getResult();
$ids = array();
foreach($objects AS $object) {
$ids[] = $object->getId();
}
/* Create missing objects and insert them into database */
for($id=$start; $id<$start+100; ++$id) {
if(in_array($id, $ids)) continue;
/* Some calculations */
$createdObject = new Object($id, $some, $data);
$em->persist($createdObject);
}
$em->flush();
Now imagine there are no objects yet (the table is clear) and one user enters the site with start=0. The script takes like 2 seconds to complete. Before it finishes - another user enters the site with start=50.
I'm not sure what exactly would happen in such scenario, but I persume that:
First user enters - the $ids array is empty, the script is generating objects with id 0-99.
Second user enters - the $em->flush form the first entrance is not yet called, which means the $ids array is still empty (I guess?). The script is generating objects with id 50-149
There is a first $em->flush() call which comes from the first user entrance. It insert objects 0-99 into the database.
There is a second $em->flush() call which comes from the second user entrance. It tries to insert objects 50-149 into the database. It fails, because the object with id=50 already exists in the database. As a result it doesnt actually insert anything into the database.
Is that what would really happen? If so - how to prevent it and what is the best way to insert only those objects that are missing into the database?
Aucun commentaire:
Enregistrer un commentaire