Parallel queries trying to create the same object if it does not exist in the Doctrine

I have a function that looks like this:

function findByAndCreateIfNotExists($criteria){ $entity = $this->findBy(['criteria'=>$criteria]); // this is the problem area, if request 1 is still creating the entity, request 2 won't find it yet. if (! $entity) { $entity = $this->createEntity($criteria); } return $entity; } 

This function is used by various queries, and I found that simultaneous queries sometimes try to create the same object by throwing a DBALException , complaining about duplicate entries for a unique key.

I was thinking about LOCK TABLES , as mentioned here: How to lock the whole table in symfony2 using doctrine2?

But just given the fact that there is no function in the Doctrine, I assume that this is not the preferred method. My question is: how can I prevent concurrent requests trying to create the same object and always return the correct one?

+1
php mysql symfony doctrine2
source share
2 answers

As an idea to create your own locking system:

something like:

 function findByAndCreateIfNotExists($criteria){ $entity = $this->findBy(['criteria'=>$criteria]); // this is the problem area, if request 1 is still creating the entity, request 2 won't find it yet. $lockPath ='/tmp/'.md5($criteria).'.lock'; if (! $entity && !file_exists($lockPath)) { $fh = fopen($lockPath, 'w') or die("Can't create file"); $entity = $this->createEntity($criteria); unlink(($lockPath); } return $entity; } 
+1
source share

But from what you said, I think that you are doing in the wrong direction, and it’s better to rebuild the application architecture a bit and put the RabbitMQ queue as an intermediate point to serve your requests.

0
source share

All Articles