I am writing a PHP function which store/updates large sets of data into a table and that may cause a deadlock. I tried investigating how to retry a failed transaction with Doctrine but sadly could not find any info online. I eventually wrote the following code
$retry = 0;
$done = false;
while (!$done and $retry < 3) {
try {
$this->entityManager->flush();
$done = true;
} catch (\Exception $e) {
sleep(1);
$retry++;
}
}
if ($retry == 3) {
throw new Exception(
"[Exception: MySQL Deadlock] Too many people accessing the server at the same time. Try again in few minutes"
);
}
My question: is there a chance this approach will insert duplicates in the database? if so, how can I force Doctrine to roll back the transactions?
Retry transaction snippet
Code
More about Doctrine transactions can be found at https://www.doctrine-project.org/projects/doctrine-dbal/en/2.7/reference/transactions.html
How to get connection:
Simply inject Doctrine's
EntityManager
(Interface
) orConnection
eg. via constructorConnection
Or EntityManager
And get connection as
$this->entityManager->getConnection()
This is how I am dealing with retrying failed transactions with Sf2.7 and doctrine 2.4.7:
If you are not using ORM then use that it will automatically managed deadlock situation.
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 :Hope this help.