Prooph Eventstore (PDO) 和 Doctrine DBAL 导致多个连接

Posted

技术标签:

【中文标题】Prooph Eventstore (PDO) 和 Doctrine DBAL 导致多个连接【英文标题】:Prooph Eventstore (PDO) and Doctrine DBAL results in multiple connections 【发布时间】:2020-01-30 11:52:11 【问题描述】:

情况

我在 Symfony 4.3 中将 Prooph 用于我的 commandbus、eventbus 和 eventstore。由于并非每个聚合都需要事件源,因此我们还使用 Doctrine DBAL 来简单地 CRUD 那些简单的聚合。

在给定的域中,我在我的命令总线中配置了命令/处理程序,它们使用事件源存储库或 DBAL 存储库。

将此命令总线注入 CLI 命令时,在 CLI 上运行任何内容时会导致多个数据库连接。

问题

当尝试删除/创建数据库(用于原始安装或重置测试环境)时,Postgres 拒绝,因为有另一个活动连接。

Could not drop database "api" for connection named default
An exception occurred while executing 'DROP DATABASE "api"':

SQLSTATE[55006]: Object in use: 7 ERROR:  database "api" is being accessed by other users
DETAIL:  There is 1 other session using the database.
我尝试禁用所有具有事件源存储库的命令 问题就解决了。 我尝试禁用所有具有 DBAL 存储库,问题已解决。 我尝试不注入此命令总线,问题已解决。

所以我可以有把握地得出结论,将带有 PDO 连接的服务与带有 DBAL 连接的服务结合使用时会出现问题。

解决方案(失败)

我想到的一个解决方案是将 Doctrine DBAL $connection->getWrappedConnection() 用于 Prooph Eventstore。显然 typehinting 不允许这样做(getWrappedConnection() 返回一个 Connection-interface),但实际的 Doctrine PDOConnection 扩展了 \PDO 如果它确实有效,我愿意在这一点上接受这个hackiness!但是,无济于事,仍然是 2 个连接。

【问题讨论】:

我认为问题来自 postgres 本身。如果您运行以下命令会发生什么: REVOKE CONNECT ON DATABASE TARGET_DB FROM public;然后: SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'TARGET_DB'; @JessGabriel 我不这么认为,在全新的环境(测试管道)中运行时也会发生这种情况,其中 de 容器 + 数据库是在 docker 中新创建的......正如我所说,当我删除了任何类型的命令,它也不会发生。所以我很确定这是因为 Symfony 的配置组件正在启动所有导致两个数据库连接的服务。 【参考方案1】:

mysqlEventStore 的构造函数的第二个参数是 PDO 连接,参见https://github.com/prooph/pdo-event-store/blob/master/src/MySqlEventStore.php#L82。您可以为 Doctrine 和 EventStore 使用相同的 PDO 实例,但这有点危险,因为您可能会干扰其事务处理。我建议在删除数据库之前关闭测试中的 Doctrine 连接。

【讨论】:

不幸的是,我已经尝试将getWrappedConnection() 教义用于事件存储(正如我在失败的解决方案中所描述的那样!)但这不起作用。至于关闭测试中的连接,我什至没有运行测试,当简单地调用 CLI 命令删除数据库时它已经失败(我这样做是为了在开始测试之前重置测试数据库)。所以这意味着当 Symfony 在内核启动时配置所有服务时,连接已经建立。 那是 symfony,而不是 prooph 问题。【参考方案2】:

简而言之,我使用延迟加载来确保在内核启动期间没有建立实际的数据库连接。请确保composer require symfony/proxy-manager-bridge 或您的lazy: true 将被默默地忽略(因此我一开始认为这不是解决方案)。

【讨论】:

以上是关于Prooph Eventstore (PDO) 和 Doctrine DBAL 导致多个连接的主要内容,如果未能解决你的问题,请参考以下文章

从 eventStore 获取特定数量的事件

分享一个CQRS/ES架构中基于写文件的EventStore的设计思路

使用 Kafka 作为 EventStore 时在 Flink 中恢复状态一致性

使用EventStore,我可以创建一个新的iCal日历类型吗?

使用 JOliver EventStore 更新多个聚合

Event Store 2.0发布,带来了安全支持和测试版Projections库