如何用Node.js将HTML表格数据存入MySQL?程序死锁求助
解决Node.js插入MySQL时的死锁问题
Hey there! 刚接触Node.js就搞自动课表生成系统,这起步挺扎实的👍 针对你遇到的MySQL死锁问题,结合你给出的代码片段,我梳理了几个常见的坑和对应的解决思路:
一、先排查连接池的连接释放问题
从代码里看到你用了连接池,这是个好习惯,但连接未正确释放是导致“假死锁”(连接池耗尽,后续请求无法获取连接)的高发原因。你要确保每次从池里拿到连接后,不管操作成功还是失败,都要调用connection.release()归还连接:
// 正确的连接池使用方式,用try/finally确保释放 pool.getConnection((err, conn) => { if (err) { console.error('获取连接失败:', err); return; } try { // 执行你的插入逻辑 conn.query('INSERT INTO your_table (...) VALUES (...)', (queryErr, results) => { if (queryErr) { console.error('插入失败:', queryErr); return; } console.log('插入成功:', results.affectedRows); }); } finally { // 不管成功失败,都要释放连接回池 conn.release(); } });
如果觉得回调写法容易遗漏释放,推荐用mysql2/promise库,结合async/await来管理,代码更清晰:
const mysql = require('mysql2/promise'); // 初始化连接池 const pool = mysql.createPool({ host: 'your_host', user: 'your_user', database: 'your_db', waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); // 用async/await执行插入 async function insertTimetableData(data) { let conn; try { conn = await pool.getConnection(); await conn.query('INSERT INTO your_table (...) VALUES (...)', [data.col1, data.col2]); } catch (err) { console.error('插入出错:', err); throw err; } finally { if (conn) conn.release(); } }
二、优化批量插入逻辑,减少数据库交互
如果是循环插入多条课表数据,单条循环插入会频繁创建数据库连接/事务,大大增加死锁概率。改成批量插入不仅能提升性能,还能降低锁冲突:
// 假设你有一个包含所有课表行的数组timetableRows const insertQuery = 'INSERT INTO timetable (course_name, class_time, classroom) VALUES ?'; // 把数组转成二维数组,对应INSERT的VALUES格式 const values = timetableRows.map(row => [row.courseName, row.classTime, row.classroom]); pool.getConnection((err, conn) => { if (err) throw err; try { conn.query(insertQuery, [values], (queryErr, results) => { if (queryErr) { console.error('批量插入失败:', queryErr); return; } console.log(`成功插入 ${results.affectedRows} 条数据`); }); } finally { conn.release(); } });
三、规范事务的使用(如果用到的话)
如果你的插入操作依赖事务,要注意不要让事务持有时间过长,避免在事务中做非数据库操作(比如读取本地文件、等待外部API响应),同时确保事务最终会commit或rollback:
pool.getConnection((err, conn) => { if (err) throw err; conn.beginTransaction((transErr) => { if (transErr) { conn.release(); throw transErr; } // 执行插入操作 conn.query('INSERT INTO timetable (...) VALUES (...)', (queryErr) => { if (queryErr) { // 出错就回滚事务 return conn.rollback(() => { conn.release(); console.error('插入失败,已回滚:', queryErr); }); } // 所有操作完成后提交事务 conn.commit((commitErr) => { conn.release(); if (commitErr) { return conn.rollback(() => { console.error('提交事务失败,已回滚:', commitErr); }); } console.log('事务提交成功'); }); }); }); });
四、数据库层面的小检查
- 确保你的课表表有合理的索引,比如针对
class_time、classroom这类经常用于查询/约束的字段建索引,避免全表扫描导致的表锁; - 如果有唯一性约束(比如同一时段同一教室不能有重复课程),要确保约束的索引是合理的,避免因冲突导致的锁等待。
最后一个小建议
代码里的var Array=require('node-array');和var s=require('string');最好改成更有意义的变量名,比如nodeArrayUtils、stringHelper,避免覆盖全局的Array对象,可能会引发一些意想不到的问题。
如果能提供完整的插入逻辑代码(比如连接池的配置、具体的插入循环/事务代码),可以更精准地定位死锁的根源哦!
内容的提问来源于stack exchange,提问作者Sharanya K G
相关产品推荐
相关产品推荐

