samedi 11 juin 2016

How does Doctrine handle multiple requests?

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:

  1. First user enters - the $ids array is empty, the script is generating objects with id 0-99.

  2. 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

  3. There is a first $em->flush() call which comes from the first user entrance. It insert objects 0-99 into the database.

  4. 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