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

MySQL连接池与事务封装问题:代码正确性及查询结果获取

问题解答

1. 当前代码的不规范点及修正

  • 连接池方法调用错误:pool.end、pool.beginTransaction、pool.commit、pool.rollback都是方法,必须加()执行,你现在await的是函数本身,不是方法执行的Promise结果,导致这些操作根本没实际执行。
  • 事务逻辑错误:连接池的事务需要基于单个连接操作,直接调用pool的事务方法不符合mysql连接池的使用规范,正确流程是从连接池获取一个连接,在该连接上开启事务、执行操作、提交/回滚,最后释放连接。
  • 错误关闭连接池:pool.end()是关闭整个连接池的方法,你的DbTransAction每次执行完都调用db.close()(即pool.end()),会直接销毁整个连接池,后续所有数据库操作都会失效。
  • 全局变量接收异步结果:用全局变量rowsA、rowsB接收异步回调的结果,属于不良编码习惯,应该通过Promise返回值或async/await链式处理结果。
  • 重复执行事务逻辑:两次调用DbTransAction,第一次执行后就关闭了连接池,第二次调用的数据库操作根本无法正常执行。

2. 无法获取查询结果的原因

  • 异步执行顺序问题:console.log是同步执行的,而DbTransAction是异步函数,还没完成数据库查询就执行了打印,此时rowsA、rowsB还未被赋值,所以输出undefined。
  • 事务封装的方法未正确执行:beginTransaction、commit等方法没有加()调用,导致事务流程根本没正常走,后续的查询操作也可能因为连接池被提前关闭而无法完成。

修正后的代码示例

// Pool settings (pool of connections).
const poolCnf = {
    connectionLimit : 10,
    host: 'myHost',
    user: 'myUser',
    password: 'myPass',
    database: 'myDB'
};

// Creating a pool for connections.
const pool = mysql.createPool(poolCnf);

// 正确的连接池事务封装:基于单个连接
async function DbTransAction(callback) {
    // 从连接池获取单个连接
    const connection = await pool.getConnection();
    try {
        // 在连接上开启事务
        await connection.beginTransaction();
        // 将连接传入回调,让回调使用该连接执行操作
        await callback(connection);
        await connection.commit();
    } catch (err) {
        await connection.rollback();
        throw err;
    } finally {
        // 释放连接回连接池,而不是关闭整个池
        connection.release();
    }
}

// 封装查询方法
async function queryWithConnection(connection, sql, args) {
    return new Promise((resolve, reject) => {
        connection.query(sql, args, (err, results) => {
            if (err) reject(err);
            else resolve(results);
        });
    });
}

// 执行查询的逻辑
async function fetchData() {
    let rowsA;
    let rowsB;
    const queryA = `SELECT * FROM games;`;
    const queryB = `SELECT * FROM sceneData;`;

    // 用同一个事务执行两个查询(如果不需要事务,也可以单独调用查询)
    await DbTransAction(async (conn) => {
        rowsA = await queryWithConnection(conn, queryA);
        rowsB = await queryWithConnection(conn, queryB);
    });

    // 确保异步操作完成后再打印
    console.log("rowsA:" + JSON.stringify(rowsA));
    console.log("rowsB:" + JSON.stringify(rowsB));
}

// 启动执行
fetchData().catch(err => console.error(err));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:00:30