[求大神] Nodejs并发情况下mysql查询错误?

[求大神] Nodejs并发情况下mysql查询错误?

使用的是 使用的mysql模块。

express + mysql 使用简单的查询语句, 在我自己在浏览器中不停的刷新 不会报错。

但是我叫我同事帮我刷新。就2台电脑同时不停刷新访问页面。就报错了。

错误信息: aaaaaaa.jpg

代码: bbbbbb.jpg

各位遇到过这个情况吗?


9 回复

当然可以!根据你的描述,问题可能出在并发请求时对数据库连接的管理不当。在Node.js中,如果你不正确地管理数据库连接,特别是在高并发环境下,可能会导致诸如连接池耗尽、资源竞争等问题。

以下是一个简单的示例,展示如何在Express应用中正确地管理MySQL连接池,以避免并发问题:

示例代码

首先,安装必要的库:

npm install express mysql2

然后,创建一个基本的Express应用,并使用mysql2模块来管理连接池:

const express = require('express');
const mysql = require('mysql2/promise'); // 使用promise版本

const app = express();
const port = 3000;

// 创建一个全局连接池
let pool;

async function init() {
    pool = mysql.createPool({
        host: 'localhost',
        user: 'yourusername',
        password: 'yourpassword',
        database: 'yourdatabase',
        connectionLimit: 10 // 设置连接池大小
    });
}

app.get('/', async (req, res) => {
    try {
        const [rows, fields] = await pool.query('SELECT * FROM your_table WHERE some_column = ?', ['some_value']);
        res.send(rows);
    } catch (error) {
        console.error(error);
        res.status(500).send('Database error');
    }
});

init().then(() => {
    app.listen(port, () => {
        console.log(`Server is running on http://localhost:${port}`);
    });
});

解释

  1. 创建连接池:在初始化函数init中,我们创建了一个连接池,限制连接数为10。这有助于防止在高并发情况下连接过多而导致的资源耗尽问题。

  2. 使用Promise:我们使用了mysql2/promise,这样可以在异步处理中更方便地使用.query方法,而不需要手动处理回调。

  3. 错误处理:在路由处理函数中,我们使用了try...catch来捕获并处理数据库查询中的任何错误。

通过这种方式,你可以更好地管理数据库连接,避免在高并发情况下出现连接池耗尽或其他资源竞争问题。希望这能帮助你解决并发查询时出现的问题!


跟SQL没有关系,是因为重复SET HEADERS导致的。

看错误日志。。这个和并发有关系吗 ,欺负我没读过书。。。。

调用init.get的时候数据库是否已关闭?我之前用mongo的时候有遇到过这个错,就是在某个函数中调用数据库,可是在另外一个函数中已经关闭数据库连接了

用连接池呗。

不好意思,之前没看你的错误信息和代码。

你的代码看不出上下文不好说。不过你的错误意思大致是一个请求你已经给它 setheader 之类的操作了然后又来一遍报的错。你看看是不是哪里重复输出了。

init.init 的问题,你的init是全局的变量,每次执行 init.init(req, res)的时候,新的req和res就会替换之前的,不同http请求都混到一起了,这个不能这么写

屏幕快照 2014-09-19 下午3.47.02.png

问题。串号了。

从描述来看,问题可能出现在并发情况下对数据库连接的管理不当导致的问题。MySQL连接并不是线程安全的,当多个请求同时尝试访问数据库时,可能会出现资源竞争或连接池配置不当的问题。

你可以尝试以下几种解决方案:

  1. 使用连接池:确保每个请求都从连接池获取一个可用的数据库连接,并在请求结束后将其归还到连接池中。
  2. 检查错误处理:确保在捕获到数据库操作异常时能够正确地处理错误,并且不会中断数据库连接的正常使用。
  3. 调整连接池配置:根据你的应用负载调整连接池的最大连接数等参数。

示例代码

安装依赖

首先,你需要安装 mysqlmysql2/promise 模块(推荐使用 mysql2,因为它提供了 promise 支持)。

npm install mysql2

使用连接池

const mysql = require('mysql2/promise');

// 创建连接池
const pool = mysql.createPool({
    host: 'localhost',
    user: 'your_username',
    password: 'your_password',
    database: 'your_database',
    waitForConnections: true,
    connectionLimit: 10, // 连接池最大连接数
    queueLimit: 0 // 等待连接队列的最大长度,为0表示无限制
});

async function queryDatabase(sql, params) {
    let connection;
    try {
        // 从连接池获取连接
        connection = await pool.getConnection();
        const [rows, fields] = await connection.query(sql, params);
        return rows;
    } catch (err) {
        console.error("Error executing query:", err);
        throw err;
    } finally {
        // 将连接归还到连接池
        if (connection) connection.release();
    }
}

app.get('/some-endpoint', async (req, res) => {
    try {
        const results = await queryDatabase('SELECT * FROM your_table');
        res.json(results);
    } catch (error) {
        res.status(500).send('Internal Server Error');
    }
});

通过这种方式,可以有效避免因并发请求导致的数据库连接错误。如果仍然遇到问题,建议进一步检查是否有其他资源的竞争或优化 SQL 查询以提高性能。

回到顶部