2014-02-12 26 views
7

我正在使用帶連接池的node-mysql驅動程序。node-mysql - 何時將連接釋放回池中

釋放連接返回到池時,只有一個查詢,很容易:

pool.getConnection(function(err, connection) { 
    if (err) { 
    throw err; 
    } 

    query = "SELECT * FROM user WHERE id = ?"; 
    connection.query(query, [id], function(err, users) { 
    connection.release(); 

    if (err) { 
     throw err; 
    } 

    // ... 
    }); 
}); 

如果我需要用第二次的連接?我必須將release()下移幾行。但是如果錯誤被拋出會發生什麼?連接是否永遠不會返回到池中?

我是否必須使用一些控制流程庫lib才能釋放它的「最終」時刻?
有什麼更好的想法?

+2

嗯。真的很好的問題!讓我思考。在每個錯誤回調中處理版本? – Zlatko

+0

@Zlatko這是我的想法,因爲當錯誤觸發 –

回答

3

可以處理的一種方法是承諾。既然你正在構建一個游泳池,您可以用的東西例如q構建您的請求(或原生的承諾,即將推出):

// assuming you have your local getConnection above or imported 
exports.getConnection = function(queryParams) { 
    var d = q.defer(); 
    local.getConnection(function(err, conn) { 
     if(err) d.reject(err); 
     d.resolve(conn); 
    }); 
}); 

所以,包你一些其他調用到這樣的承諾,然後就撰寫查詢:

db.getConnection() 
.then(function(conn){ 
    makeRequest() 
    .then(...) 
    ... 
.catch(function(err){ 
    // at the end you release the conn 
}); 

這看起來像是你要求的東西嗎?

+0

時,這個連接永遠不會回到池中,這是我最終做的 - 但帶有承諾和生成器。謝謝你指點我正確的方向。 – pkyeck

+0

等待,如果在catch塊中釋放錯誤,這隻會釋放連接嗎?難道你不想做'.finally(function(){conn.release();}' – PixMach

+0

哦,你可以這樣做,我想你可以做''makeRequest'中釋放連接,但最後會更好。 – Zlatko

1

當您執行MySQL查詢時,此時它會鎖定數據庫,直到查詢完成。查詢成功完成後,它釋放該數據庫鎖定。

同樣的情況在這裏:connection.release();只是簡單地釋放數據庫連接,沒有別的。

0

您應該爲這種情況使用單獨的連接。這就是連接池的用途。這樣一個人不必等待另一個完成才能開始。如果一個查詢在其他查詢完成之前無法啓動,則只使用相同的連接。