尝试创建相同实体的并发请求(如果不存在于Doctrine中) [英] Concurrent requests trying to create the same entity if not exists in Doctrine

查看:63
本文介绍了尝试创建相同实体的并发请求(如果不存在于Doctrine中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的功能:

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;
}

这个函数被各种请求使用,我发现并发请求有时会尝试创建相同的实体,抛出一个 DBALException 抱怨唯一键的重复条目。

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 '$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $¬$ a-whole-table-in-symfony2-with-doctrine2>如何用doctrine2锁定symfony2中的整个表?

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

但只是给出了一个事实在Doctrine中没有这样做的功能,我猜这不是首选的方法。我的问题是,如何防止并发请求尝试创建相同的实体并始终返回正确的一个?

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?

推荐答案

创建自己的锁定系统:

如下所示:

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;
}

这篇关于尝试创建相同实体的并发请求(如果不存在于Doctrine中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆