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
相关产品推荐
相关产品推荐

