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

Next.js读取RDS(MySQL)数据异常,求排查修复方案

问题:Next.js + mysql2/promise 从RDS读取数据时数据损坏

刚接触Next.js,使用mysql2/promise从RDS(MySQL)读取数据时遇到以下异常:

  • 单条数据可正常展示,读取两条及以上数据时出现数据损坏;
  • 单条数据读取成功的情况下,当result_description列文本长度超过约150字符时,数据也会损坏。

已排查JSON格式干扰问题,调整该列varchar最大长度后问题仍存在,相关代码如下:

lib/db.js

import mysql from "mysql2/promise";

export async function LibDB(query, values) {
    const DbConnection = await mysql.createConnection({
        host: process.env.DB_HOST,
        port: process.env.DB_PORT,
        user: process.env.DB_USER,
        password: process.env.DB_PASS,
        database: process.env.DB_DATABASE
    });

    try {
        const [results] = await DbConnection.execute(query, values)
        DbConnection.end();
        return results

    } catch (error) {
        throw Error(error.message);

    }

}

pages/api/get_result.js

import{LibDB} from "../../lib/db"

export default async function handler(req, res) {

    try {

        const query = "SELECT T.test_id, T.test_share, R.test_title, R.result_title, R.result_name, R.result_description, R.result_sub_description, R.result_image, R.result_image_kakao, R.result_image_facebook FROM tests_results R INNER JOIN logs L ON L.test_id = R.test_id AND L.result_type = R.result_type INNER JOIN tests T ON R.test_id = T.test_id WHERE L.log_id = ? AND L.test_id = ?";
        const value = [req.query.logId, req.query.testId];
        const data = await LibDB(query,value);

        // res.status(200).json({results: data})
        res.status(200).send(data);

    } catch (error) {

        res.status(500).json({error: error.message})
        res.status(500).send('error')
    }

}

API调用代码

export async function getServerSideProps({params}){
    const response = await axios.get(process.env.NEXT_PUBLIC_URL+"/api/get_result", {params: {logId: params.id, testId:1}})
        const data =response.data
        return {
            props:{resultData: data}
        };
}

排查与修复方案

1. 修复响应序列化方式

当前API使用res.send(data)直接返回数据,该方法在处理复杂对象或长文本时,易因编码、序列化不完整导致数据损坏。必须改用res.json(),它会自动完成标准JSON序列化,适配多数据、长文本场景。

修改pages/api/get_result.js的响应代码:

// 替换原res.status(200).send(data);
res.status(200).json({ results: data });

同时调整调用端getServerSideProps的取值逻辑:

const data = response.data.results;

2. 改用数据库连接池

每次请求创建新连接并手动关闭,可能因连接提前断开导致数据未完全读取。改用mysql2/promise的连接池,可自动管理连接生命周期,稳定性更高:

修改lib/db.js为连接池模式:

import mysql from "mysql2/promise";

// 创建连接池
const pool = mysql.createPool({
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    user: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: process.env.DB_DATABASE,
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

export async function LibDB(query, values) {
    try {
        const [results] = await pool.execute(query, values);
        return results;
    } catch (error) {
        throw new Error(error.message);
    }
}

无需手动关闭连接,连接池会自动回收。

3. 检查字符编码与列类型

  • 确认数据库、表、result_description列的字符编码为utf8mb4,避免特殊字符、长文本转义出错;
  • 若该列存储大段文本,建议将类型从varchar改为text或longtext,varchar的长度限制可能导致序列化截断。

4. 修正错误处理逻辑

当前API的catch块同时调用res.json()和res.send(),会导致重复发送响应引发异常,保留一种即可:

catch (error) {
    res.status(500).json({ error: error.message });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:40:46