避免并发请求中的数据库错误(PHP和Symfony)

时间:2017-10-05 08:38:56

标签: php mysql symfony doctrine-orm

我有一个PHP 7.1和Symfony 3.2的服务器API休息。我有一个请求,检查用户是否有草稿,如果他没有草稿,则会创建草稿。当同一用户发出两个并发请求时,会发生此问题。两个请求都通过验证,并看到用户没有草稿。当第一个到达时创建草稿,稍后到达的草稿会尝试创建它并抛出一个学说例外。

[Exception]: Doctrine \ DBAL \ Exception \ UniqueConstraintViolationException

[message]: An exception occurred while executing 'INSERT INTO ChecklistDraft (id, title, description, estimated_time, creator_id) VALUES (?,?,?,?)' with params [101, null, null, null, 50121] :
SQLSTATE [23000]: Integrity constraint violation: 1062 Duplicate entry '50121' for key 'UNIQ_910CB4B461220EA6' .

[file]: /project/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php .

服务器返回500,这不应该发生。我可以控制所有请求中的异常,但如果在另一个请求中我使代码错误并抛出异常,我将不会得到通知。

1 个答案:

答案 0 :(得分:0)

documentation of doctrine解释了如何处理这个问题。

我认为最适合您的方法是创建一个学说交易,只捕获where而不是Doctrine\DBAL\Exception\UniqueConstraintViolationException这样:

\Exception

当您在回滚后不再抛出异常对象时捕获$em->getConnection()->beginTransaction(); // suspend auto-commit try { //... do some work $em->persist($draft); $em->flush(); $em->getConnection()->commit(); } catch (Doctrine\DBAL\Exception\UniqueConstraintViolationException $e) { $em->getConnection()->rollBack(); } 类,您可以隐藏其他难以找到的问题,这也可能导致其他问题(例如,当您使用PHPSpec测试代码时以及您的代码可以捕获PHPSPec异常