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

React+Node.js+MariaDB架构下执行数据库更新后后端随机挂起问题求助

核心问题原因

你遇到的服务挂起最核心的诱因是POST接口处理完成后没有给客户端返回任何响应,HTTP请求会一直处于挂起状态:

  • 浏览器对同域名的并发请求数有默认限制(一般为6个),几次点击操作产生的POST请求全部挂起后,后续的轮询GET请求会进入浏览器的待发送队列完全卡住
  • 未关闭的请求也会持续占用Node服务和数据库连接池的连接资源,最终导致服务无响应
  • 重启服务时所有挂起的连接被强制断开,队列中积压的请求集中执行,才会出现日志批量打印的情况

其他需要修复的风险点

  1. 两个接口的异常捕获逻辑直接throw err,没有返回错误响应,遇到数据库操作异常时同样会导致请求挂起
  2. POST接口直接拼接SQL字符串,存在严重的SQL注入风险
  3. 前端用固定间隔setInterval轮询,不感知上一个请求是否完成,网络延迟高时会出现请求堆积
  4. 前端getSelPos方法中打印的selPos变量未定义,会抛出未捕获异常

修复后的代码

Node后端修改

const express = require('express')
const db = require('./db')
const app = express()
const port = 5000
const bodyParser = require("body-parser");
 
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    next();
});
// GET接口修复:异常时返回错误响应
app.get('/selector', async (req, res) => {
    try {
        const result = await db.pool.query("select value from db.tags where tag='1006'");
        res.send(result[0].value.toString());
        console.log(result[0].value.toString());
    } catch (err) {
        console.error(err);
        res.status(500).send('查询失败');
    }
});
// POST接口修复:新增响应返回、使用参数化查询防注入
app.post('/selector', async (req, res) => {
    try {
        // 不同数据库驱动的参数化查询写法略有差异,可根据你用的驱动适配
        const result = await db.pool.query("update db.tags set value = ? where tag='1006'", [req.body.position]);
        console.log(result);
        res.send('更新成功'); // 必须返回响应结束本次请求
    } catch (err) {
        console.error(err);
        res.status(500).send('更新失败');
    }
});

app.listen(port, () => console.log(`Listening on port ${port}`));

React前端修改

// 改成动态轮询,等上一次请求完成后再触发下一次,避免请求堆积
componentDidMount() {
    this.pollingEnabled = true;
    this.runPolling();
}
  
componentWillUnmount() {
    this.pollingEnabled = false;
    if (this.pollingTimer) clearTimeout(this.pollingTimer);
}
  
runPolling() {
    if (!this.pollingEnabled) return;
    this.getSelPos().finally(() => {
        this.pollingTimer = setTimeout(() => this.runPolling(), 2000);
    })
}

getSelPos() {
    return axios.get("http://localhost:5000/selector",  { crossdomain: true }).then(response => {
        console.log(response.data);
        this.setState({SelectorPos: parseInt(response.data)}, () => {
            // 确保state更新完成后再打印
            console.log("Selpos is" + this.state.SelectorPos);
        });
    }).catch(err => {
        console.error('获取位置失败', err);
    });
}

setSelPos(i) {
    axios.post("http://localhost:5000/selector",  { position: i }).then((response) => {
        console.log(response);
    }, (error) => {
        console.log(error);
    });
}

handleClick(i){
    this.setSelPos(i);
}

额外优化建议

检查你的数据库连接池配置,建议将最大连接数调整到10~20,避免并发请求多时连接不够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:27:03