pool.query()和pool.getGetConnection()在connection.release()上有何不同?

Roe*_*oel 8 mysql connection-pooling node.js node-mysql

我可以理解每一个pool.query()都会花费一个连接,它会在结束时自动释放.基于这个关于github问题的评论.但是使用的嵌套查询pool.getConnection()呢?

pool.getConnection(function(err, connection) {

  // First query
  connection.query('query_1', function (error, results, fields) {

    // Second query
    connection.query('query_2', function (error, results, fields) {

          // Release the connection
          // DOES THIS ALSO RELEASE query_1?
          connection.release();

          if (error) throw error;

          // you can't use connection any longer here..
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

UPDATE

这是执行嵌套查询时使用事务的代码.

const pool = require('../config/db');

function create(request, response) {
   try {

       pool.getConnection(function(err, con) {

           if (err) {
               con.release();
               throw err;
           }

           con.beginTransaction(function(t_err) {

               if (t_err) {
                   con.rollback(function() {
                      con.release();
                      throw t_err;
                   });
               }


               con.query(`insert record`, [data], function(i_err, result, fields){

                   if (i_err) {
                       con.rollback(function() {
                           con.release();
                           throw i_err;
                       });
                   }


                   // get inserted record id.
                   const id = result.insertId;

                   con.query(`update query`, [data, id], function(u_err, result, fields)=> {

                       if (u_err) {
                          con.rollback(function() {
                             con.release();
                             throw u_err;
                          });
                       }

                       con.commit(function(c_err){
                          if (c_err) {
                             con.release();
                             throw c_err;
                          }
                       });

                       con.release();

                       if (err) throw err;

                       response.send({ msg: 'Successful' });
                   });
               });

           });
       });

   } catch (err) {
      throw err;
   }
}
Run Code Online (Sandbox Code Playgroud)

我做了很多防御性错误捕获,con.release()因为此时我不知道如何正确释放每个处于活动状态的连接.

我还假设每个con.query()内部pool.getConnection()都需要连接.

Mar*_*per 7

编辑:

A connection就像是将您的应用程序连接到数据库的电线。每次您connection.query()要做的都是沿着那条电线发送一条消息时,您并没有在更换电线。

当你问pool一个connection,它要么给你一个“线”它已经到位或创建一个新的线到数据库中。当您release()使用池化连接时,池将对其进行回收,但是会保留一段时间,以防您再次需要它。

因此query,连接线上的消息是。您可以根据需要发送任意多的消息,它仅一根电线。


原始答案

pool.query(statement, callback) 本质上是

const query = (statement, callback) => {
    pool.getConnection((err, conn) => {
        if(err) {
            callback(err);    
        } else {
            conn.query(statement, (error, results, fields) => {
                conn.release();
                callback(error, results, fields);
            });
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,您不必担心往返的次数。您可以multipleStatements: true在构建池时在池配置中启用多个语句,然后利用事务。

BEGIN;
INSERT ...;
SELECT LAST_INSERT_ID() INTO @lastId;
UPDATE ...;
COMMIT;
Run Code Online (Sandbox Code Playgroud)