2016-09-13 63 views
0

我有一個表叫做疫苗。對於每種疫苗都有一定數量的批次和一定數量的病理學,所以我爲批次(VacLots)和病理學(VacPathologies)創建了一張表格。依賴於mysql節點中第一個結果的表執行查詢

Vaclots和VacPathologies都使用疫苗標識符進行索引。

要創建一個疫苗,我會做一個查詢來檢索所有疫苗(針對特定的國家)以及每個需要執行兩個額外查詢的標識符:一個用於標識其批次,另一個用於標識其病理。

該代碼: 這是用於執行具有指定參數的查詢的函數。

executeQueryWithParams(queryToExecute, queryArgs, processRow) { 
    this.pool.getConnection((err, conn) => { 
     if (err) { 
      console.log(`${err} executing the query ${queryToExecute} for database ${this.pool}`); 
      cb({reason: 'Failed to get connection', err}); 
     } else { 
      let query = conn.query(queryToExecute, queryArgs, (error, rows) => { 
       conn.release(); 
       if (error) { 
        cb({reason: `Failed to execute query ${queryToExecute}`, error}); 
       } else { 
        cb(null , rows); 
       } 
     }); 
} 

這是接收國家ID並負責創建疫苗對象的功能。

getVaccinesForCountryID = function (countryID) { 
return new Promise((resolve, reject) => { 
    database.executeQueryWithParams(queries[GET_VACCINE_QUERY_INDEX], [countryID], function(err, rows) { 
    if (err || rows.length == 0) { 
     reject(utils.isNullOrUndefined(err) ? new Error('Empty results') : err); 
    } else { 
     resolve(processResultRows(rows)); 
    } 
    }); 
}); 

處理結果函數。

function processResultRows(rows) { 
    const promiseArray = []; 
    for (const row of rows) { 
    const vaccine = instantiateVaccine(row); 
    promiseArray.push(hydrateVaccine(vaccine)); 
    } 
    return Promise.all(promiseArray); 
} 

的instantiateVaccine功能不只是創造一些行中已經提供的信息的疫苗對象。

function hydrateVaccine(vaccine) { 
    return getLotsForVaccine(vaccine).then(data => getPathologiesForVaccine(data)); 
} 

檢索一個特定疫苗的地段。

function getLotsForVaccine(vaccine) { 
    return getDetailsVaccine(GET_VACCINE_LOTS_QUERY_INDEX, vaccine, (vac, rows) => { 
    const lotsArray = []; 
    for (const row of rows) { 
     lotsArray.push({lot: row.lot}); 
    } 
    vac.lots = lotsArray; 
    }); 
} 

檢索特定疫苗的病理。

function getPathologiesForVaccine(vaccine) { 
    return getDetailsVaccine(GET_VACCINE_PATHOLOGIES_QUERY_INDEX, vaccine, (vac, rows) => { 
    const pathologiesArray = []; 
    for (const row of rows) { 
     pathologiesArray.push({pathology: row.pathology}); 
    } 
    vac.pathologies = pathologiesArray; 
    }); 
} 

泛型函數來獲取一些細節(無論是地段或病理)

function getDetailsVaccine(queryIndex, vaccine, hydrateFunction) { 
    return new Promise((resolve, reject) => { 
    database.executeQueryWithParams(queries[queryIndex], [vaccine.identifier], (err, rows) => { 
     if (err) { 
     reject({error: err, query: queries[queryIndex], identifier: vaccine.identifier}); 
     } else { 
     hydrateFunction(vaccine, rows); 
     resolve(vaccine); 
     } 
    }); 
    }); 

這一切運作良好,如果沒有大量的請求,正在發生,但一旦發生超過10個請求(實例使用ab -k -c 2 -n 10)我得到拒絕連接,池的最大連接數爲1000.

我覺得我的回調和Promise混合可能是一個問題,但我目前無法實現executeQueryWithParams函數作爲Promise。

編輯: 這是一個用於創建池的代碼(如this.pool在executeQueryWithParams函數引用)

const pool = mysql.createPool({ 
    connectionLimit : '1000', 
    host      : 'localhost', 
    user     : 'readOnlyUser', 
    password    : 'hRND74SKUjuH4uLU', 
    database    : 'Calendar', 
    debug   : false 
}); 
+0

你在哪裏創建了連接?你可以在這裏發帖嗎? – abdulbarik

+0

我已添加所需的代碼。 – Diogo

+0

你可以試試100個connectionLimit嗎? – abdulbarik

回答

1

通過@abdulbarik指示我會後我自己的解決方案。

以下面的方式實現executeQueryWithParams允許用戶使用帶有Promise的mysql池,這已經在總共100000個連接上測試了500個併發連接,並且沒有TOO_MUCH_CONNECTIONS錯誤的問題,並且可以用作承諾,如果你想鏈。

function executeQueryWithParams(queryToExecute, queryArgs) { 
    return new Promise((resolve, reject) => { 
    this.pool.query(queryToExecute, queryArgs, function(err, rows) { 
     if (err) { 
     reject({reason: 'Error executing query', err}); 
     } else { 
     resolve(rows); 
     } 
    }); 
    }); 
} 
相關問題