带有 MySQL 错误的 TypeORM:池已关闭。调用数据库时测试卡住

Posted

技术标签:

【中文标题】带有 MySQL 错误的 TypeORM:池已关闭。调用数据库时测试卡住【英文标题】:TypeORM with MySQL Error: Pool is closed. Test is getting stuck when calling the Database 【发布时间】:2020-12-28 20:00:22 【问题描述】:

TypeORM 有一个奇怪的问题,特别是 Jest(可能相关,也可能不相关)。某个测试完全卡住/挂起,我们很难找出问题所在。

就堆栈而言:Typescript, NodeJS, Apollo Graphql, Jest, mysql。 有问题的测试实际上是使用 Apollo 的集成测试框架进行的集成测试。

首先发生的是一个特定的测试完全卡住了,几分钟后控制台中抛出了一个错误:QueryFailedError: ER_LOCK_WAIT_TIMEOUT: Lock wait timeout exceeded; try restarting transaction

为了查明问题,我找到了我们在 afterEach 上运行的一个函数,它“破坏”了数据库。它最初运行:

await queryRunner.query('DELETE FROM Table1');
await queryRunner.query('DELETE FROM Table2');
...

错误和“死锁”最初在我将其从 queryRunner 更改为 queryBuilder 后得到修复:

await queryBuilder.delete().from('Table1').execute();
...

这是在使用SHOW PROCESSLIST;SHOW ENGINE InnoDB STATUS; 试图弄清楚发生了什么之后完成的。我还将事务隔离更改为 READ-COMMITTED 但无济于事。除了将其从 queryRunner 更改为 queryBuilder 之外,没有任何效果。

这工作了一段时间,但现在似乎测试又卡住了(测试没有改变,但它正在测试的代码)。现在测试挂起后,我们得到这个错误:Error: Pool is closed。之后测试被“发布”,所有的测试都开始一一失败。

我们发现这是导致测试卡住的事件序列:

1. open a transaction with queryRunner
2. perform a read query
3. then perform a write
4. commit the transaction and release the queryRunner
5. delete the DB
6. perform a write - deadlock

此外,我们注意到以下几点:

如果我们确保只使用 queryRunner 进行更新,而不是 对于查询,则不会发生死锁。

更改代码,以便我们首先使用常规连接进行所有读取查询 对象(不是 queryRunner)只有这样如果我们连接 queryRunner 并进行所有写入 - 然后不会发生死锁。

有人对可能发生的事情有任何见解吗? queryRunner 是否存在一些不稳定因素或我们在使用它时需要考虑的一些特定事项?

谢谢!

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,我的问题是未处理的异步/等待。 检查是否未处理某些承诺对象。 如果使用 async 关键字,则必须使用 await 关键字处理所有异步函数。 也不要忘记调用jest 的done 方法。

【讨论】:

他的问题出在数据库锁上,所以我不相信和async/await有什么关系 我遇到了同样的问题,出现错误Pool is closed,原因是忘记了await关键字。因此,连接在函数执行实际结束之前关闭。

以上是关于带有 MySQL 错误的 TypeORM:池已关闭。调用数据库时测试卡住的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 TypeOrm 的 NestJS 连接 MySQL 数据库时出现问题

测试时池已关闭(HikariDataSource)

如何修复预期值:“1”接收到的数组:[“COUNT (*)”:“1”] 在带有 jest 框架的 TypeORM 中出现错误

在 TypeORM 中使用 QueryBuilder 与 Repository 都有哪些不同的用例? [关闭]

如何修复预期值:“1”收到的数组:带有jest框架的TypeORM中的[{“COUNT(*)”:“1”}]错误

Typeorm 插入数据,即使它存在