【问题标题】:Doctrine 2 Concurrency issues原则 2 并发问题
【发布时间】:2016-08-07 23:49:02
【问题描述】:

我正在为 Symfony 2 / Doctrine 2 应用程序编写单元测试,我遇到了看起来像并发问题的问题。

代码如下所示:

$obj = new Obj();
$obj->setName('test');

... etc ...

$em->persist($obj);
$em->flush();

...

$qb = $em->getRepository('Obj');
// Select object using DQL

$this->assertTrue($obj !== null);

此时 $obj 通常为空。 IE。 DQL 查询未能找到它。如果我在执行 DQL 之前在某处添加断点并暂停执行,则始终会找到 $obj。如果不是,通常找不到,但偶尔会找到。

我已尝试将插入包装在事务中:

$em->getConnection()->beginTransaction();

$obj = new Obj();
$obj->setName('test');

... etc ...

$em->persist($obj);
$em->flush();

$em->getConnection()->commit();

这似乎没有帮助。

我尝试在插入和 DQL 查询之间添加暂停:

sleep(1); 

这会始终如一地产生预期的行为。因此我的结论是这是一个并发问题。或者至少与 Doctrine 没有在刷新时立即写完有关。

Doctrine 2 有什么方法可以强制完成对数据库的写入吗?还是要听的事件?还是我在这里做错了什么?

【问题讨论】:

  • 为您的数据库服务器启用查询日志并查看查询是如何发出的。对于您观察到的并发问题,您必须有 2 个同时运行的连接。第一个是可能的但不太可能,第二个在 php 中是不可能的(默认情况下)。
  • 看来并发毕竟不是问题。我发现了一个与时间相关的错误,导致我的结果不一致。如果您想添加有关日志记录的评论作为答案,我会将其标记为答案,因为我在遵循您的建议后立即发现了我的错误。
  • 你最好发布答案并解释问题
  • 我已经发布了一个答案,但我想给你声望点...谢谢你的提示。

标签: php symfony concurrency doctrine-orm


【解决方案1】:

按照 zerkms 的建议启用日志记录后,我迅速将问题追溯到我自己的代码中的错误。没有并发问题。

在我的 Mac 上,我执行了以下操作:

编辑:/usr/local/etc/my.cnf 添加这些行:

general_log_file = /tmp/query.log
general_log      = 1

然后:

brew services restart apache2

接下来我跟踪文件:

tail -f /tmp/query.log

我看到两个查询 - 一个插入和一个选择 - 以正确的顺序执行。直接在 MySQL 客户端中运行这些查询发现了我的代码中的错误。

注意:将日志放入/tmp/ 可确保每次我注销时都会删除日志。

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多