nodejs連接mysql突然中斷問題解決方案


db/index.js數據庫配置文件

一、在數據庫連接失敗的情況下,回調函數,再次發起連接,直到連接成功為止。

handleDisconnect(){
   this.connection.connect(function(err) {              
        if(err) {                                    
        //   console.log('error when connecting to db:', err);
          setTimeout(_this.handleDisconnect, 2000);
        }                                    
    });                                  
    this.connection.on('error', function(err) {
        if(err.code === 'PROTOCOL_CONNECTION_LOST') { 
            _this.handleDisconnect();                         
        } else {                                     
            throw err;                                 
        }
    }); 
}

二、mysql在8個小時內沒有任何操作,就會自動中斷連接
因此,每個三個小時每個小時ping一次數據庫,保持數據庫連接狀態

clearInterval(pingInterval);
pingInterval = setInterval(() => {
    _this.connection.ping((err) => {
        if (err) {
            console.log('ping error: ' + JSON.stringify(err));
        }
    });
}, 3600000*3);

三、完整代碼如下:

// 加載數據庫模塊
var mysql = require('mysql');
var _this;
var pingInterval = null;
var db_config = {
    host: "host",  //主機地址
    user: "user", //數據庫用戶名
    password: "password", //數據庫用戶密碼
    database: "database"  //數據庫名
}
class DB{
    constructor(){
        _this = this;
        this.connection = null;
    }
    handleDisconnect(){
        this.connection = mysql.createConnection(db_config);
        //數據庫連接 
        this.connection.connect(function(err) {              
            if(err) {                                    
            //   console.log('error when connecting to db:', err);
              setTimeout(_this.handleDisconnect, 2000);
            }                                    
        });                                  
        this.connection.on('error', function(err) {
            if(err.code === 'PROTOCOL_CONNECTION_LOST') { 
                _this.handleDisconnect();                         
            } else {                                     
                throw err;                                 
            }
        });
        // 每個小時ping一次數據庫,保持數據庫連接狀態
        clearInterval(pingInterval);
        pingInterval = setInterval(() => {
            _this.connection.ping((err) => {
                if (err) {
                    console.log('ping error: ' + JSON.stringify(err));
                }
            });
        }, 3600000*3);
        return this.connection;
    }
}

module.exports = DB;
使用數據庫的文件controller/query.js

在開啟事務的時候判斷數據庫連接是否連接錯誤,
如果連接錯誤,再次發起連接。

db.beginTransaction((err)=>{
    if(err!==null){
        db = _this.handleDisconnect();
        db.beginTransaction((err)=>{
            callback(err)
        })
    }else{
        callback(err)
    }
})

完整代碼如下:

const DB = require("../../db/index");
const Async = require("async");
var db;
class Query extends DB{
    constructor(){
        super()
        db = this.handleDisconnect()
    }
    async getList(limit,page,cate,keywords,grade){
        return new Promise((resolve, reject) => {
            var mydatas = {data:[],total:0};
            
            // ....此處省略業務代碼
            
            // 用Async代替嵌套
            var task = [
                (callback)=>{
                    // 開啟事務
                    db.beginTransaction((err)=>{
                        if(err!==null){
                            db = _this.handleDisconnect();
                            db.beginTransaction((err)=>{
                                callback(err)
                            })
                        }else{
                            callback(err)
                        }
                    })
                },
                (callback)=>{
                    const sql = `...`;
                    db.query(sql,(err,res)=>{
                        callback(err);
                    })
                },
                (callback)=>{
                    // 提交事務
                    db.commit((err)=>callback(err));
                }
            ];
            Async.waterfall(task,(err,res)=>{
                if(err){
                    // 事務回滾
                    db.rollback();
                }else{
                    resolve(mydatas);
                }
            })
        })
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM