Node mysql 程序运行一段时间后,读写数据库出现异常?

发布于 2022-09-07 11:49:35 字数 1035 浏览 26 评论 0

程序使用 Node 编写,后端数据库为 MySQL,提供 APP 后端 API 及 socket 连接服务。目前单实例部署,实例内使用一个 MySQL 连接。服务初期工作一切正常,随着服务时间变长(一天到一周不等),某个时间点,一个 API 调用会发生失败,发生该错误之后,后续的所有数据库读写操作都会失败。API 服务代码出错的原因是:向 MySQL 插入一条记录失败,我在关键代码处插入了一些代码:

self.conn.query(sql, function(err, res, fields){
        if(err){
            callback && callback(ERRCODE.MYSQL.code, err);
        }else{
            if (!res.insertId) {
                logger.error('activity.insertActivitySpeaker: insertId undefined');
            } else {
                logger.info('success: activity.insertActivitySpeaker: insertId %s', res.insertId);
            }
            callback && callback(0, res);
        }
    });

比较难理解的是,插入操作失败时,代码

logger.info('success: activity.insertActivitySpeaker: insertId %s', res.insertId);

仍被执行,且打印了一个正常的 id(自增),但是 MySQL binlog 中并无相应的操作日志,且最终数据库里也查不到 id 对应的那条记录。目前猜测是服务长时间运行或代码逻辑漏洞导致 MySQL 连接异常:向 MySQL 尝试写入时,可以获得一个写入 id,但最终的写入操作未执行成功,而从数据库读取的操作,返回的数据都是空。不知朋友们有没有遇到过类似问题,给些排查建议,万分感谢。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╄→承喏 2022-09-14 11:49:35

问题原因是使用事务时,缺少 rollback 或 commit,使用以下代码可稳定复现这个错误:

let mysql = require("mysql");

function createConn() {
    return mysql.createConnection({
        host     : '192.168.1.100',
        user     : 'yangqiang',
        password : '123456',
        database : 'node_mysql_demo'
    });
}

function transactionWithoutCommit(conn) {
    conn.beginTransaction(function (err) {
        if (err) {
            throw err;
        }
        conn.query('SELECT * from user where name="jonny"', function (error, results, fields) {
            if (error) {
                return conn.rollback(function () {
                    throw error;
                })
            } else {
                // 缺少 commit,引发错误
            }
        });
    });
}

function transactionWithCommit(conn) {
    conn.beginTransaction(function (err) {
        if (err) {
            throw err;
        }
        conn.query('SELECT * from user where name="jonny"', function (error, results, fields) {
            if (error) {
                return conn.rollback(function () {
                    throw error;
                })
            } else {
                conn.commit(function (err) {
                    if (err) {
                        return conn.rollback(function(){ throw err;})
                    } else {
                        console.log('transaction committed');
                    }
                });
            }
        });
    });
}

function write(conn) {
    conn.query('INSERT INTO user (name) VALUES ("Mei");', function (error, results, fields) {
        if (error) throw error;
        console.log(JSON.stringify(results));
    });
}


var connection = createConn();
connection.connect();

transactionWithoutCommit(connection); // 引发错误
// transactionWithCommit(connection); // 正确的方法
write(connection);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文