const mysql = require("mysql2/promise"); class DBPool { constructor(coin, options) { this.coin = coin; this.pool = mysql.createPool(options); } /** * 非事务SQL操作 * @param {String} sql * @param {Array} values * @returns */ async exec(sql, values = []) { const con = await this.pool.getConnection(); try { const [data] = await con.query(sql, values); return data; } catch (err) { throw err; } finally { con.release(); } } /** * 单独SQL事务操作 * @param {String} sql * @param {Array} values * @returns */ async exec_transaction(sql, values = []) { const con = await this.pool.getConnection(); try { await con.beginTransaction(); const [data] = await con.query(sql, values); await con.commit(); return data; } catch (err) { await con.rollback(); throw err; } finally { con.release(); } } /** * 执行一系列 SQL 操作,合并到一个事务中。 * @param {Array} params [{sql:"", param:[param1, param2, ...]}] */ async exec_transaction_together(params) { const con = await this.pool.getConnection(); try { await con.beginTransaction(); // 确保所有查询都完成后再提交事务 for (const { sql, param } of params) { await con.query(sql, param); } await con.commit(); } catch (err) { await con.rollback(); throw err; } finally { con.release(); } } async exec_write_lock(sql, values = [], table_name) { const con = await this.pool.getConnection(); try { await con.beginTransaction(); // 使用模板字符串而不是占位符来构建 LOCK TABLES 语句 await con.query(`LOCK TABLES ${table_name} WRITE`); await con.query(sql, values); await con.commit(); } catch (err) { await con.rollback(); throw err; } finally { await con.query("UNLOCK TABLES"); con.release(); } } } module.exports = DBPool