Concurrent requests trying to create the same entity if not exists in Doctrine

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-23 03:28:09

问题


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 requests, and I've found that concurrent requests will sometimes try to create the same entity, throwing a DBALException complaining about duplicate entries for the unique key.

I've thought about LOCK TABLES as mentioned here: How to lock a whole table in symfony2 with doctrine2?

But just given the fact there is no function to do this in Doctrine, I'm guessing it's not the preferred method. My question is, how can I prevent concurrent requests attempting to create the same entity and always return the correct one?


回答1:


As idea create 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;
}



回答2:


But from what you told I think you are doing in wrong direction and it is better to rebuild app architecture little bit and put RabbitMQ queue as intermediate point to serve your requests



来源:https://stackoverflow.com/questions/29644717/concurrent-requests-trying-to-create-the-same-entity-if-not-exists-in-doctrine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!