如何在异常后的长时间运行过程中使用Doctrine Entity Manager

时间:2017-03-06 06:45:58

标签: php symfony doctrine-orm doctrine

我的问题是关于哲学而非技术问题。

关于Doctrine的EM的几句话。如果在工作期间发生任何异常,它会关闭连接并清除自身:与数据库的连接失败(传入任务数量较少的长时间运行的消费者中的常见情况),SQL语句中的错误或与DB服务器相关的其他内容,或者EM本身。在此EM实例完全无法使用之后。

所以,真实世界的例子:我有一个队列和消费者,它作为控制台工作者运行并等待任务。消费者有下一个依赖:

  • EntityManager(EM)
  • Service1 - >有依赖来自EM和Doctrine Repository1
  • Service2 - >具有EM和Doctrine Repository2的依赖性
  • ServiceN - >具有来自EM和Doctrine RepositoryN的依赖

如果EM服务失败 - 服务(1-N)和存储库(1-N)(取决于此EM)在调用时也会抛出错误,因为EM不再正常工作。在这种情况下我该怎么做?

  1. “let-it-crash”:工作人员因错误而停止并稍后重新加载 supervisord。导致增加无用错误的数量 日志\标准错误,
  2. 在每次迭代中使用$connection->ping()做一些魔术:实际上,ping()只执行SELECT 1;,因此,这会导致 增加对DB服务器无用查询的数量。
  3. 与之前相同,但是如果EM失败,则在消费者上创建新的:在每次迭代时执行ping(),如果失败 - 创建新的EM。 但是,消费者使用的所有服务也应该重新创建,所以我 每个人都需要一个工厂。这种方式导致数量增加 消费者中的类和更复杂的逻辑:重新创建所有 使用new或old进行每次迭代的服务(及其依赖项) EM,或检测EM重新创建并重新创建所有相关服务 仅在新EM的情况下。但这会导致抽象泄漏:消费者 不应该知道它使用什么EM实例 - 旧的或新的,并且应该 不要做这些糟糕的事情。
  4. 处理这件事的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

我会在这里分享一些想法。

  1. "导致日志\ stderr"中的无用错误数量增加 - 我不认为这些是无用的错误。如果您的软件抛出异常,您应该知道这一点。如果软件没有任何例外,那么该软件的日志文件是最好的,但这种情况很少见。无论如何,应该调查任何数据库异常及其发生的速率。

  2. 我不会依赖重新建立连接,而是依靠Doctrine API来初始化自己。 This answer有一些关于如何为多个Doctrine2版本执行此操作的详细信息。

  3. 我认为这太过于实施的逻辑,只会使问题复杂化。

  4. 如果我选择,我会使用选项#1(让它崩溃),因为它是最简单的,它不会隐藏任何东西。