101

MySQL を最も効率的に使用するようにアプリケーションを構成する方法を見つけようとしています。node-mysql モジュールを使用しています。ここの他のスレッドは接続プールを使用することを提案したので、小さなモジュール mysql.js をセットアップしました

var mysql = require('mysql');

var pool  = mysql.createPool({
    host     : 'localhost',
    user     : 'root',
    password : 'root',
    database : 'guess'
});

exports.pool = pool;

mysql にクエリを実行するときはいつでも、このモジュールが必要であり、データベースにクエリを実行します。

var mysql = require('../db/mysql').pool;

var test = function(req, res) {
     mysql.getConnection(function(err, conn){
         conn.query("select * from users", function(err, rows) {
              res.json(rows);
         })
     })
}

これは良いアプローチですか?メインのapp.jsスクリプトですべてが行われる非常に単純なもの以外に、mysql接続を使用する例をあまり見つけることができなかったため、規則/ベストプラクティスが何であるかがよくわかりません。

各クエリの後に常に connection.end() を使用する必要がありますか? どこかに忘れたら?

毎回 getConnection() を記述する必要がないように、接続のみを返すように mysql モジュールのエクスポート部分を書き直すにはどうすればよいですか?

4

8 に答える 8

74

良いアプローチです。

接続を取得したいだけの場合は、プールがあるモジュールに次のコードを追加します。

var getConnection = function(callback) {
    pool.getConnection(function(err, connection) {
        callback(err, connection);
    });
};

module.exports = getConnection;

毎回 getConnection を記述する必要があります。ただし、最初に接続を取得したときにモジュールに接続を保存できます。

使用が終わったら、接続を終了することを忘れないでください。

connection.release();
于 2013-08-28T19:45:33.923 に答える
39

pool.getConnection()できれば使用を避けるべきです。を呼び出すpool.getConnection()場合は、接続の使用が終了したときに呼び出す必要があります。connection.release()そうしないと、接続制限に達すると、接続がプールに返されるのを永遠に待機して、アプリケーションがスタックしてしまいます。

単純なクエリの場合は、 を使用できますpool.query()connection.release()この短縮形は、エラー状態であっても自動的に呼び出します。

function doSomething(cb) {
  pool.query('SELECT 2*2 "value"', (ex, rows) => {
    if (ex) {
      cb(ex);
    } else {
      cb(null, rows[0].value);
    }
  });
}

ただし、場合によっては、 を使用する必要がありますpool.getConnection()。これらのケースは次のとおりです。

  • トランザクション内で複数のクエリを実行します。
  • 後続のクエリ間で一時テーブルなどのデータ オブジェクトを共有します。

を使用する必要がある場合は、次のようなパターンを使用してpool.getConnection()呼び出すようにしてください。connection.release()

function doSomething(cb) {
  pool.getConnection((ex, connection) => {
    if (ex) {
      cb(ex);
    } else {
      // Ensure that any call to cb releases the connection
      // by wrapping it.
      cb = (cb => {
        return function () {
          connection.release();
          cb.apply(this, arguments);
        };
      })(cb);
      connection.beginTransaction(ex => {
        if (ex) {
          cb(ex);
        } else {
          connection.query('INSERT INTO table1 ("value") VALUES (\'my value\');', ex => {
            if (ex) {
              cb(ex);
            } else {
              connection.query('INSERT INTO table2 ("value") VALUES (\'my other value\')', ex => {
                if (ex) {
                  cb(ex);
                } else {
                  connection.commit(ex => {
                    cb(ex);
                  });
                }
              });
            }
          });
        }
      });
    }
  });
}

Promise私は個人的にs とuseAsync()パターンを使用することを好みます。asyncこのパターンを/と組み合わせると、レキシカル スコープが への自動呼び出しに変わるため、await誤って接続を忘れることがはるかに難しくなります。release().release()

async function usePooledConnectionAsync(actionAsync) {
  const connection = await new Promise((resolve, reject) => {
    pool.getConnection((ex, connection) => {
      if (ex) {
        reject(ex);
      } else {
        resolve(connection);
      }
    });
  });
  try {
    return await actionAsync(connection);
  } finally {
    connection.release();
  }
}

async function doSomethingElse() {
  // Usage example:
  const result = await usePooledConnectionAsync(async connection => {
    const rows = await new Promise((resolve, reject) => {
      connection.query('SELECT 2*4 "value"', (ex, rows) => {
        if (ex) {
          reject(ex);
        } else {
          resolve(rows);
        }
      });
    });
    return rows[0].value;
  });
  console.log(`result=${result}`);
}
于 2019-01-16T19:53:20.010 に答える
14

私はmysqlでこの基本クラス接続を使用しています:

「base.js」

var mysql   = require("mysql");

var pool = mysql.createPool({
    connectionLimit : 10,
    host: Config.appSettings().database.host,
    user: Config.appSettings().database.username,
    password: Config.appSettings().database.password,
    database: Config.appSettings().database.database
});


var DB = (function () {

    function _query(query, params, callback) {
        pool.getConnection(function (err, connection) {
            if (err) {
                connection.release();
                callback(null, err);
                throw err;
            }

            connection.query(query, params, function (err, rows) {
                connection.release();
                if (!err) {
                    callback(rows);
                }
                else {
                    callback(null, err);
                }

            });

            connection.on('error', function (err) {
                connection.release();
                callback(null, err);
                throw err;
            });
        });
    };

    return {
        query: _query
    };
})();

module.exports = DB;

そのように使用してください:

var DB = require('../dal/base.js');

DB.query("select * from tasks", null, function (data, error) {
   callback(data, error);
});
于 2017-01-04T21:50:15.337 に答える
2

接続が完了したら、呼び出すだけでconnection.release()接続がプールに戻り、他の誰かが再び使用できるようになります。

var mysql = require('mysql');
var pool  = mysql.createPool(...);

pool.getConnection(function(err, connection) {
  // Use the connection
  connection.query('SELECT something FROM sometable', function (error, results, fields) {
    // And done with the connection.
    connection.release();

    // Handle error after the release.
    if (error) throw error;

    // Don't use the connection here, it has been returned to the pool.
  });
});

接続を閉じてプールから削除したい場合は、connection.destroy()代わりに を使用してください。プールは、次に接続が必要になったときに新しい接続を作成します。

ソース: https://github.com/mysqljs/mysql

于 2018-02-23T12:13:30.407 に答える
-7

私は常にconnection.relase()を使用します。pool.getconnetion の後

pool.getConnection(function (err, connection) {
      connection.release();
        if (!err)
        {
            console.log('*** Mysql Connection established with ', config.database, ' and connected as id ' + connection.threadId);
            //CHECKING USERNAME EXISTENCE
            email = receivedValues.email
            connection.query('SELECT * FROM users WHERE email = ?', [email],
                function (err, rows) {
                    if (!err)
                    {
                        if (rows.length == 1)
                        {
                            if (bcrypt.compareSync(req.body.password, rows[0].password))
                            {
                                var alldata = rows;
                                var userid = rows[0].id;
                                var tokendata = (receivedValues, userid);
                                var token = jwt.sign(receivedValues, config.secret, {
                                    expiresIn: 1440 * 60 * 30 // expires in 1440 minutes
                                });
                                console.log("*** Authorised User");
                                res.json({
                                    "code": 200,
                                    "status": "Success",
                                    "token": token,
                                    "userData": alldata,
                                    "message": "Authorised User!"
                                });
                                logger.info('url=', URL.url, 'Responce=', 'User Signin, username', req.body.email, 'User Id=', rows[0].id);
                                return;
                            }
                            else
                            {
                                console.log("*** Redirecting: Unauthorised User");
                                res.json({"code": 200, "status": "Fail", "message": "Unauthorised User!"});
                                logger.error('*** Redirecting: Unauthorised User');
                                return;
                            }
                        }
                        else
                        {
                            console.error("*** Redirecting: No User found with provided name");
                            res.json({
                                "code": 200,
                                "status": "Error",
                                "message": "No User found with provided name"
                            });
                            logger.error('url=', URL.url, 'No User found with provided name');
                            return;
                        }
                    }
                    else
                    {
                        console.log("*** Redirecting: Error for selecting user");
                        res.json({"code": 200, "status": "Error", "message": "Error for selecting user"});
                        logger.error('url=', URL.url, 'Error for selecting user', req.body.email);
                        return;
                    }
                });
            connection.on('error', function (err) {
                console.log('*** Redirecting: Error Creating User...');
                res.json({"code": 200, "status": "Error", "message": "Error Checking Username Duplicate"});
                return;
            });
        }
        else
        {
            Errors.Connection_Error(res);
        }
    });
于 2016-08-29T09:32:15.780 に答える