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

解决MySQL/Node.js MERN应用自动重复执行数据库查询问题

解决MySQL替代MongoDB后MERN应用重复执行查询的问题

嘿,作为全栈新手遇到这种问题确实头疼,咱们结合你给的代码片段一步步来排查和解决:

最可能的原因:后端未返回响应导致前端重试

你后端的/addAlbum路由调用了album.add()但没有给前端返回任何响应,axios在等待超时后会自动重试请求(默认配置下可能会重试1-2次),这就会导致后端重复执行查询。这是这类问题最常见的诱因!

修复步骤:

  1. 修改album.add函数,加入回调来处理查询结果:
// album模块的add方法
function add(Album_title, Artist, Release_date, Category, Description, Rotation, callback) {
  const insertAlbumQuery = "INSERT INTO albums (title, artist, release_date, category, description, rotation) VALUES (?, ?, ?, ?, ?, ?)"; // 替换成你的实际查询语句
  const insertAlbumValues = [Album_title, Artist, Release_date, Category, Description, Rotation];
  
  db.query(insertAlbumQuery, insertAlbumValues, function(err, result) {
    if (err) {
      console.error("添加专辑失败:", err);
      return callback(err);
    }
    console.log("1 Album added.");
    callback(null, result);
  });
}
  1. 在POST路由中返回响应给前端:
router.post("/addAlbum", (req, res) => {
  const { Album_title, Artist, Release_date, Category, Description, Rotation } = req.body;
  album.add(Album_title, Artist, Release_date, Category, Description, Rotation, (err, result) => {
    if (err) {
      return res.status(500).json({ success: false, message: "添加专辑失败" });
    }
    res.status(200).json({ success: true, message: "专辑添加成功", insertId: result.insertId });
  });
});
  1. 前端可以给axios请求加个loading状态,避免用户重复点击:
addAlbum = currentState => {
  if (this.state.isLoading) return; // 防止重复提交
  this.setState({ 
    Rotation: +this.state.Rotation,
    isLoading: true
  }, () => {
    axios.post("http://localhost:3001/api/addAlbum", this.state)
      .then(response => {
        console.log(response.data);
        // 这里可以做成功后的操作,比如清空表单
      })
      .catch(err => {
        console.error("请求失败:", err);
      })
      .finally(() => {
        this.setState({ isLoading: false });
      });
  });
};

优化MySQL连接:用连接池代替单连接

你现在用的是单连接全程保持开启,虽然单例模式没问题,但在高并发场景下会导致查询排队,也增加了连接异常的风险。换成连接池能自动管理连接,减少内存泄漏和睡眠查询的隐患:

修改数据库连接代码:

let mysql = require("mysql");
// 创建连接池
const pool = mysql.createPool({
  host: "******",
  user: "******",
  password: "******",
  database: "******",
  connectionLimit: 10 // 根据你的并发量调整
});

module.exports = pool;

之后查询时直接用pool.query,不需要手动管理连接,连接池会自动回收空闲连接:

// album模块的add方法改成用pool.query
pool.query(insertAlbumQuery, insertAlbumValues, function(err, result) {
  // ... 回调逻辑不变
});

其他排查方向

如果修复以上问题后还是有重复查询,可以试试:

  • 检查前端按钮是否被多次绑定点击事件(比如组件渲染时多次调用addAlbum的绑定),可以在addAlbum开头加console.log("发送添加请求"),看点击一次是否打印多次。
  • 查看MySQL的慢查询日志或进程列表,确认重复查询的来源(是否是同一个连接发起的)。
  • 检查后端是否不小心重复注册了/addAlbum路由(比如多次导入router模块)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:00:27