Friday, March 18, 2016

Doctrine/PostgreSQL not running every update on my script

Leave a Comment

I'm running a dozen update statements on a script and some updates just won't happen, I need to know why and how to fix this situation.

I have this piece of code:

foreach($clis as $c => $cli) {       //... do some stuff     foreach($emails as $e)    {             $Mailqueue = $this->em->getRepository('Sendsys\Entity\Mailqueue')->findBy(array("email" => $e,"status" => "P"));             foreach($Mailqueue as $queue)             {                 $queue->setStatus('S');                 $this->em->persist($queue);             }                    }     $this->em->flush(); //entity manager is retrieved before that } 

This basically run through a (somewhat large) table to update the emails with status 'P' to 'S', these emails are on a list in the $emails array.

I have tried using doctrine's ExecuteUpdate with a prepared statement instead of retrieving and persisting an entity each time , but it results in the exact same issue.

Some more details:

The issue happens even with the mail sending function commented out

I know that all of the emails are being sent (when uncommented) and the script is generating all of the update statements, I've output them when testing ExecuteUpdate

I know that the updates are getting to Postgres because some rows do update and if I refresh the rows will randomly update until there is none left

I can't just update everything afterwards, I need to know where the script stopped in case of failure.

EDIT

It's not doctrine related, I've connected directly to the database and ran the followings statements inside a loop:

    $dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);      $stmt = $dbh->prepare("UPDATE mailqueue SET status = 'S' WHERE status = :status AND email LIKE :mail");      $stmt->execute(array( ':status' => 'P', ':mail' => $e ));      echo $stmt->rowCount();  

2 Answers

Answers 1

Calling $this->em->persist($queue); isn't necessary (You can delete it). Recall that this method simply tells Doctrine to manage or "watch" the $queue object. In this case, since you fetched the $queue object from Doctrine, it's already managed.

Answers 2

The statements of updates are run only at the end by $this->em->flush(); This is the only action that tells Doctrine to begin the SQL transaction, if you need updates te bo executed before that, just call the flush method.

During the treatments before flushing, the changes remain in the entities linked to the manager.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment