You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeORM 0.3.0+版本DataSource连接池突然关闭问题咨询

TypeORM 0.3.x 并发请求报「Pool is closed」问题解决方案

问题复现场景

  • 项目封装了独立的数据库控制器类,在TypeORM 0.3.7版本中通过如下逻辑初始化DataSource:
const dataSource: DataSource = new DataSource({
    type: "mariadb",
    host: process.env.DB_HOST,
    username: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: database,
    logging: false,
    name: UUID.v4(),
    synchronize: false,
    entities: [path.join(__dirname, "../", "Models", "*.js")]
});

const createdConnection: DataSource = await dataSource.initialize();

return Promise.resolve(new ReturnStatus(true, "Connection created", createdConnection));
  • 业务层通过如下方式并发拉取数据:
Promise.all([GetSites(), GetDetails(), GetCategories()]);
  • 服务端处理逻辑:每个请求方法都会独立调用上述控制器逻辑,创建全新的DataSource实例,运行时抛出如下错误:
Error: Pool is closed.
    at Handshake.onConnect (C:\Users\<USER>\Project\node_modules\mysql\lib\Pool.js:52:15)
    at Handshake.<anonymous> (C:\Users\<USER>\ProjectAPI\node_modules\mysql\lib\Connection.js:526:10)
  • 版本关联:相同代码在升级到TypeORM 0.3.7前可正常运行,实测该问题从TypeORM 0.3.0版本变更后开始出现。

核心原因

TypeORM 0.3.x版本重构了整套连接管理逻辑:

  1. 0.2.x版本存在全局连接管理器,所有通过name标识的连接都会被全局持有引用,不会被垃圾回收,即使每次请求生成随机UUID的新连接,也会被全局缓存,不会触发连接池销毁。
  2. 0.3.x版本移除了全局连接管理器,不再自动持有DataSource实例的引用。当前在请求方法内创建局部DataSource实例,方法执行完后实例失去引用,会被V8垃圾回收,回收时会自动销毁关联的数据库连接池。并发场景下,其他正在执行的请求如果拿到了正在被销毁的连接池引用,就会抛出Pool is closed错误。

正确使用方式

不需要执行额外初始化操作,也不需要回退到已废弃的Connection API,按照官方推荐的单例模式使用即可:

  • 废弃「请求级别创建DataSource实例」的逻辑,在应用启动阶段全局初始化一次DataSource,后续所有数据库操作都复用这同一个实例。
  • 不需要调用已标记为废弃的datasource.connect()方法,initialize()方法已经完成了连接池初始化、实体注册的全部流程,初始化完成即可直接使用。
  • DataSource内部自带连接池管理,并发请求下会自动分配、回收连接,不需要为每个请求单独创建连接。

全局初始化示例:

// 全局导出唯一的DataSource实例,整个应用生命周期复用
export const AppDataSource = new DataSource({
    type: "mariadb",
    host: process.env.DB_HOST,
    username: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: database,
    logging: false,
    // 全局单例不需要生成随机name,可直接删除该配置
    synchronize: false,
    entities: [path.join(__dirname, "../", "Models", "*.js")],
    // 可根据业务并发量配置连接池参数
    pool: {
        max: 10,
        min: 2
    }
});

// 应用启动入口处执行一次初始化即可
await AppDataSource.initialize();

后续业务代码中,直接导入AppDataSource获取Repository、执行查询即可,并发场景下也不会出现连接池关闭的问题。

补充:如果有多数据源动态切换的需求,也需要为每个数据库维护长生命周期的DataSource实例,禁止在请求级别频繁创建、销毁DataSource实例,否则不仅会触发连接池错误,还会带来反复新建连接的性能损耗。

内容的提问来源于stack exchange,提问作者user17145524

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:24:28