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() на несколько строк вниз. Но что произойдет, если ошибка будет выброшена? Соединение никогда не возвращается в пул?

Должен ли я использовать какую-либо библиотеку управления потоком, чтобы иметь «наконец» момент, когда я мог ее выпустить?
Есть идеи получше?


person Philipp Kyeck    schedule 12.02.2014    source источник
comment
Хм. Действительно хороший вопрос! Заставил меня задуматься. Обрабатывать выпуск в каждом обратном вызове ошибки?   -  person Zlatko    schedule 13.02.2014
comment
@Zlatko это то, о чем я думал, так как это соединение никогда не возвращалось в пул, когда возникала ошибка   -  person Roel    schedule 26.10.2017


Ответы (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
});

Это похоже на то, о чем вы просите?

person Zlatko    schedule 12.02.2014
comment
именно это я и сделал, но с промисами и генераторами. спасибо, что указали мне правильное направление. - person Philipp Kyeck; 13.02.2014
comment
Подождите, разве это не освободит соединение только в случае возникновения ошибки, поскольку вы освобождаете в блоке catch? Разве вы не хотели бы сделать .finally(function(){ conn.release(); } ?? - person Z2VvZ3Vp; 30.01.2015
comment
О, вы можете сделать это, я думал, что вы можете сделать, чтобы разорвать соединение в makeRequest, но, в конце концов, было бы намного лучше. - person Zlatko; 31.01.2015

Когда вы выполняете запрос MySQL, на это время он блокирует базу данных до завершения запроса. После успешного завершения запроса он освобождает эту блокировку базы данных.

Здесь тот же случай: connection.release(); просто разрывает соединение с БД, ничего больше.

person Ambrish Rajput    schedule 30.03.2015

Вы должны использовать отдельные соединения для этой ситуации. Вот для чего нужен пул соединений. Таким образом, одному не нужно ждать, пока другой закончит, прежде чем он сможет начаться. Я использую одно и то же соединение только в том случае, если один запрос не может начаться, пока другой запрос не завершится.

person Peter Smartt    schedule 23.02.2016