在Symfony 3.2(使用PHP-FPM在Apache上运行)中,我们提供了一个REST API,它允许通过请求中的JSON有效载荷发布新实体。
我们的 API 流量不高,但在这种特定情况下,我们的前端会同时向我们的 API 触发 20 个 POST 请求>。
今天,我们第一次(此应用程序自 3 年以来一直在运行)在生产中收到以下错误消息,用于这些请求之一:
完整性约束冲突:1062/home/vcap/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php' (...) 中键"主要"的重复条目"5372">
Doctrine\DBAL\Exception\UniqueConstraintViolationException:执行 'INSERT INTO our_entity 时发生异常(ourfield1, ourfield2, ourfield3,...)值 (?, ?, ?, ?, ?, ?, ?, ?, ?,...
不幸的是,我们的生产日志记录在这里停止,这是另一个问题
我们不做
- 此处的任何更新(不是之前也不是之后)
- 我们没有其他的唯一约束验证
- 我们使用标准的自动 ID 生成器来对抗标准的MariaDB 数据库
- 当然,之前我们的数据库中没有存在具有此ID的实体
最后,这是一个简单的
// Step 1 - create and flush new Entity
$newEntity = new OurEntity();
$newEntity->setValues($valuesFromJsonPayload);
$em->persist($newEntity);
$em->flush();
// Step 2 - get ID and store it with another object
$em->refresh($newEntity);
$generatedId = $newEntity->getId();
$history = new History();
$history->setNewId($generatedId);
$em->persist($history);
$em->flush();
我什至不明白为什么我会在这里提到步骤2,因为根据错误消息,步骤 1显然会出现问题。
在我们要求用户再次简单地执行相同的操作后,它就像一个魅力。
任何想法为什么会发生?
这可能有点偏离主题,但是:
我不建议对 ID 使用数据库自动增量。
例如,您可以使用 Uuid 库。该 ID 将是一个随机哈希字符串。实体对象将具有 ID,并在实例化后立即生效。而且您不必仅仅为了获取 ID 而将其保存到数据库。
就在昨天,我给出了类似的答案。看看故事的其余部分和参考资料。