尝试创建相同实体的并发请求(如果不存在于Doctrine中) [英] Concurrent requests trying to create the same entity if not exists in 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屋!