如果所有的客户端都公用一个mysql 连接会有问题吗?

现在我们经常使用数据库连接池,因为数据库连接是有上限的也比较耗费资源,经常的打开关闭连接也耗时和浪费系统资源尤其在高并发的场景下
那这样的话可不可以所有的数据库客户端公用一个数据库连接呢?该链接默认是不会被客户端关闭的

阅读 5.4k
6 个回答

一个TCP连接是不能并发传输的,只能串行传输。
如果你的并发量很大,会导致并发堆积,所有的客户端都在MySQL传输的TCP上等待传输。
连接池就是为了解决这个问题的,每个客户端只在传输的时候独占一个TCP连接,当数据传输完了,放回连接池,这条TCP连接还可以被重复利用。

一般情况下,连接池也不是越大越好,连接池过多会导致CPU调度的时候上下文切换过于频繁,消耗很多资源,建议的连接池数量为:连接数 = ((核心数 2) + 有效磁盘数),一般设置为:((核心数 2) + 1)比较合适。

更多可以参考这篇文章: https://zhuanlan.zhihu.com/p/...

额,共用一个连接??? 那如果一个查询耗时1秒,一百个人在等这个连接,最后一个人不会要等100秒???

当然不能,如果其中一个请求发生异常,不是所有人的修改都会被回滚?

MySQL一个连接就是一个线程,多个客户端共用一个连接,很关键的问题就是单线程阻塞。

数据库连接是半双工的,就是说只能发送一个指令(sql),然后获得结果,在获得结果之前不能再发送新的指令,如果只有一个连接,连续查询没有等到前面查询结果返回(不知道前面有没有查询)就会出错,如果加锁,并发性能肯定很差,不知道为啥不想用连接池,所有的网络连接都不是线程安全的,如果你就一个线程用不用连接池都可以,一个连接就能搞定,但是多个线程执行的时候用一个连接是不安全的,即使可以同时发两个请求,你不知道那个结果是你的,即使可以使用一个连接,你能知道哪个返回是谁的,但是半双工的连接要么写要么读,你想想那得有多慢

// Conn is a connection to a database. It is not used concurrently
// by multiple goroutines.
//
// Conn is assumed to be stateful.
type Conn interface {
    // Prepare returns a prepared statement, bound to this connection.
    Prepare(query string) (Stmt, error)

    // Close invalidates and potentially stops any current
    // prepared statements and transactions, marking this
    // connection as no longer in use.
    //
    // Because the sql package maintains a free pool of
    // connections and only calls Close when there's a surplus of
    // idle connections, it shouldn't be necessary for drivers to
    // do their own connection caching.
    Close() error

    // Begin starts and returns a new transaction.
    //
    // Deprecated: Drivers should implement ConnBeginTx instead (or additionally).
    Begin() (Tx, error)
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题