Typeorm+NestJS原生查询触发ER_CON_COUNT_ERROR:连接数过多问题求助
解决TypeORM每次查询创建新连接导致连接数过多的问题
问题根源
你的DBDataSource类每次调用_mysql方法时都会新建一个DataSource实例,每个实例都会创建独立的数据库连接池。随着请求量增加,连接数会迅速超过MySQL的最大连接限制,触发ER_CON_COUNT_ERROR错误。
解决方案:单例连接池复用
重构代码,确保整个应用只初始化一个DataSource实例,共用同一个连接池。
1. 重构DBDataSource类(单例连接)
修改data-source.ts,将DataSource作为类的成员变量,仅初始化一次:
import { DataSource } from "typeorm"; export class DBDataSource { private readonly dataSource: DataSource; constructor() { // 初始化唯一的DataSource实例 this.dataSource = new DataSource({ type: "mysql", host: process.env.DATABASE_HOST, port: 3306, username: process.env.DATABASE_USER, password: process.env.DATABASE_PASS, database: process.env.DATABASE_NAME, synchronize: false, // 配置连接池参数,限制最大连接数(根据MySQL配置调整) poolSize: 10, }); // 预初始化连接(或在第一次查询时懒加载) this.initConnection(); } private async initConnection() { if (!this.dataSource.isInitialized) { try { await this.dataSource.initialize(); console.log("数据库连接初始化成功"); } catch (error) { console.error("数据库连接初始化失败:", error?.message); } } } async mysql(query: string, parameters?: any[]) { // 确保连接已初始化 await this.initConnection(); // 使用参数化查询避免SQL注入风险 return this.dataSource.query(query, parameters); } }
2. 在NestJS中注册单例服务
在你的根模块(如app.module.ts)中,将DBDataSource注册为单例,确保整个应用共享同一个实例:
import { Module } from '@nestjs/common'; import { DBDataSource } from './Config/data-source'; import { BookService } from './book.services'; import { HttpModule } from '@nestjs/axios'; @Module({ imports: [HttpModule], // 导入HttpModule以提供HttpService providers: [ BookService, { provide: DBDataSource, useValue: new DBDataSource(), // 单例实例 }, ], }) export class AppModule {}
3. 修改查询代码,避免SQL注入
更新book.services.ts,使用参数化查询替代字符串拼接:
import { Injectable} from '@nestjs/common'; import { DBDataSource } from '../Config/data-source'; import { HttpService } from '@nestjs/axios'; @Injectable() export class BookService { constructor( private httpService: HttpService, private readonly dbDataSource: DBDataSource ) {} async GET_BookByID(id: string){ // 参数化查询:用?占位符,参数放在数组中 const resbook = await this.dbDataSource.mysql( 'SELECT * FROM mst_book WHERE id = ?', [id] ); return resbook; } }
关键说明
- 连接池复用:现在整个应用只有一个
DataSource实例,TypeORM会自动管理连接池,复用空闲连接,避免重复创建连接。 - 连接数控制:通过
poolSize配置连接池最大连接数,不要超过MySQL的max_connections设置(默认151)。 - 安全修复:参数化查询彻底避免了SQL注入风险,这是字符串拼接查询的严重安全漏洞。
内容的提问来源于stack exchange,提问作者riski
相关产品推荐
相关产品推荐

