How to retry transaction after a deadlock using Doctrine?

A deadlock returns error 1213 which you should process on the client side

Note that a deadlock and lock wait are different things. In a deadlock, there is no "failed" transaction: they are both guilty. There is no guarantee which one will be rolled back.

You must use rollback, your style code will insert duplicate. for example you should :

$retry = 0;

$done = false;


$this->entityManager->getConnection()->beginTransaction(); // suspend auto-commit

while (!$done and $retry < 3) {

    try {

        $this->entityManager->flush();

        $this->entityManager->getConnection()->commit(); // commit if succesfull

        $done = true;

    } catch (\Exception $e) {

        $this->entityManager->getConnection()->rollback(); // transaction marked for rollback only

        $retry++;

    }

}

Hope this help.


This is how I am dealing with retrying failed transactions with Sf2.7 and doctrine 2.4.7:

use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\ORM\EntityManager;

class Foo
{
    /**
     * @var Registry
     */
    protected $doctrine;

    public function __construct(Registry $registry)
    {
        $this->doctrine = $registry;
    }

    protected function doSomething($entity, $attempt)
    {
        $em = $this->getEntityManager();
        $conn = $em->getConnection();
        try{
            $conn->beginTransaction();
            $entity->setBar("baz");
            $em->flush();
            $conn->commit();
        } catch(\PDOException $e){
            $conn->rollBack();
            $attempt++;
            if($attempt <= 3){
                $this->doSomething($repayment, $attempt);
            }
        }
    }

    /**
     * @return EntityManager
     */
    protected function getEntityManager()
    {
        /** @var EntityManager $em */
        $em = $this->doctrine->getManager();
        if(!$em->isOpen()){
            $this->doctrine->resetManager();
            $em = $this->doctrine->getManager();
        }

        return $em;
    }
}