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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:02:08