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

每次API调用新建tedious连接是否合理?Express对接SQL Server连接方案咨询

结论

你当前每次请求新建、销毁数据库连接的做法是非常不推荐的生产环境实践,核心原因如下:

  • 连接建立开销高:每次新建连接需要完成TCP三次握手、SQL Server身份校验、会话上下文初始化等多个步骤,会显著拉高接口的响应延迟
  • 容易耗尽数据库资源:SQL Server的最大连接数存在默认上限,高并发场景下大量临时连接会占满连接配额,直接导致后续所有连接请求被数据库拒绝
  • 资源利用率低:频繁创建销毁连接会浪费服务端和数据库两端的CPU、内存资源,拉高整体服务的资源消耗
更优方案:使用数据库连接池

连接池会预先创建一批可复用的数据库连接,请求到来时直接从池内取空闲连接使用,使用完毕后归还到池中,不需要销毁连接,从根本上避免了反复创建连接的额外开销。tedious从v14版本开始已经内置了ConnectionPool实现,不需要引入额外第三方依赖,具体实现参考如下:

第一步:全局初始化连接池

在项目启动时初始化一次连接池即可,不要重复初始化:

// db.js 全局数据库配置文件
import { ConnectionPool } from 'tedious';

const poolConfig = {
  max: 10, // 池内最大连接数,根据业务并发量调整,不要超过SQL Server的最大连接限制
  min: 2, // 池内最小保持的空闲连接数
  idleTimeoutMillis: 30000, // 空闲连接超时时间,超时后自动销毁
  ...getConfig() // 复用你原有配置里的数据库地址、账号、密码、库名等参数
};

export const pool = new ConnectionPool(poolConfig);

// 全局监听连接池异常
pool.on('error', err => {
  console.error('数据库连接池异常:', err);
});

第二步:接口层调用连接池

import { pool } from './db.js';
export class Controller {
  async all(_: Request, res: Response): Promise<void> {
    let connection;
    try {
      // 从连接池获取空闲连接
      connection = await pool.acquire();
      // 执行查询逻辑
      const result = await getProducts(connection);
      res.json(result);
    } catch (err) {
      console.error('查询失败:', err);
      res.status(500).json({ error: '内部服务错误' });
    } finally {
      // 用完归还连接到池内,不要调用close方法关闭
      if (connection) {
        connection.release();
      }
    }
  }
}

第三步:查询逻辑封装

import { Request as SqlReq } from 'tedious';
export default function getProducts(connection) {
  return new Promise((resolve, reject) => {
    const query = `SELECT * FROM Production.Product FOR JSON PATH;`;
    let resultJson = '';

    const sqlReq = new SqlReq(query, (err) => {
      if (err) return reject(err);
      resolve(JSON.parse(resultJson));
    });

    sqlReq.on('row', columns => {
      columns.forEach(column => {
        if (column.value) resultJson += column.value;
      });
    });

    connection.execSql(sqlReq);
  });
}
补充注意事项
  • 连接池的max参数不要设置过大,一般单服务实例设置10-20即可,超过SQL Server的连接上限反而会导致所有请求失败
  • 一定要在finally块里归还连接,避免请求异常时连接被永久占用,最终导致池内连接耗尽
  • 如果你使用的tedious版本低于v14,可以使用tedious-connection-pool2第三方包实现连接池,API逻辑和上述示例基本一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:33:00