【问题标题】:Why do we need to release connection when using connection pool in mysql?为什么在mysql中使用连接池时需要释放连接?
【发布时间】:2019-11-28 23:11:06
【问题描述】:

我正在尝试按照this 教程实现nodejs mysql 数据库。我知道

pool.query() 是 pool.getConnection() + connection.query() + connection.release().

文章中数据库配置为:

var mysql = require('mysql')
var pool = mysql.createPool({
    connectionLimit: 10,
    host: 'localhost',
    user: 'matt',
    password: 'password',
    database: 'my_database'
})
pool.getConnection((err, connection) => {
    if (err) {
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
            console.error('Database connection was closed.')
        }
        if (err.code === 'ER_CON_COUNT_ERROR') {
            console.error('Database has too many connections.')
        }
        if (err.code === 'ECONNREFUSED') {
            console.error('Database connection was refused.')
        }
    }
    if (connection) connection.release()
    return
})
module.exports = pool

这可以用作:

pool.query('SELECT * FROM users', function (err, result, fields) {
    if (err) throw new Error(err)
    // Do something with result.
})

但是,我真的不明白这一点

if (connection) connection.release()

如果使用池自动释放连接,为什么我们需要这个?

【问题讨论】:

    标签: mysql node.js


    【解决方案1】:

    一旦您执行pool.getConnection(),您将从池中删除一个连接,然后您可以使用该连接,并且没有其他人可以从池中访问该连接。完成后,将其放回池中,以便其他人使用。

    因此,当不使用pool.query()(如您所知,它会自动将其放回池中)时,您必须建立连接,使用它做任何您想做的事情,然后自己将其放回池中。

    如果您只需要一个查询,则使用pool.query() 并让它自动从池中获取连接,运行查询,然后将其释放回池中。但是,如果您要对连接执行多项操作,例如多次查询或多次插入数据库,则获取连接,对其执行多项操作,然后将其释放回池中。从池中手动获取连接还允许您在该连接上建立状态并在多个操作之间共享该状态。对pool.query() 的两次连续调用实际上可能使用来自池的不同连接。它们甚至可以并行运行。

    但是,我真的不明白这一点

    if (connection) connection.release()

    如果使用池自动释放连接,为什么我们需要这个?

    如果您手动从池中获取连接,那么当您使用connection.release() 完成连接后,您必须手动将其放回池中。否则,连接池很快就会空无连接,而您将拥有一堆任何人都无法使用的空闲连接。

    如果你使用像pool.query()这样的自动方法,那么它会在单次查询操作后处理将其放回池中。

    可以将其视为自动模式与手动模式。手动模式让您可以更好地控制您的工作方式,但当自动模式符合您的需求时,它更易于使用。当自动模式 (pool.query()) 不能完全满足您的要求时,请手动从池中获取连接,使用它并将其放回原处。

    【讨论】:

    • 当您说多个插入或查询时,您的意思是运行依赖于其他查询结果的查询吗?
    • @jedu - 我不太了解mysql,但文档指的是连接状态,例如事务、变量值、当前用户等......
    • @jedu 它们本身不必相互依赖,但如果其中一个成功而另一个失败,那么这将使数据库处于不一致的状态。考虑具有两个表的示例:user_account(用户名,密码)和 user_profile(姓名,姓氏,出生日期)。每当创建一个新帐户时,都需要进行两次插入。如果第一个成功而第二个失败(通过使用 2 * pool.query() ),那么你就有麻烦了。在这种情况下,您应该使用手动连接,以便您使用 connection.rollback() 来“撤消”第一个成功的查询并保持数据库一致
    猜你喜欢
    • 2017-08-02
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 2015-07-29
    • 2014-08-06
    • 2013-05-01
    • 2016-10-24
    相关资源
    最近更新 更多