Go语言 sql连接与连接池


原文链接: Go语言 sql连接与连接池

最大连接 包含4类 1. 已经建立的连接(正在使用) 2.空闲连接(使用完毕) 3. 新建连接(正在创建) 4. 未创建的连接

连接池配置

配置连接池有两个的方法:

db.SetMaxOpenConns(1000)
设置打开数据库的最大连接数。该函数的默认设置是0,表示无限制。 包含正在使用的连接和连接池的连接。
如果你的函数调用需要申请一个连接,并且连接池已经没有了连接或者连接数达到了最大连接数。此时的函数调用将会被block,直到有可用的连接才会返回。设置这个值可以避免并发太高导致连接mysql出现too many connections的错误。

db.SetMaxIdleConns(100) 设置连接池中的保持连接的最大连接数。默认是2,
设置为0表示连接池不会保持释放连接池中的连接的连接状态:即当连接释放回到连接池的时候,连接将会被关闭。这会导致连接再连接池中频繁的关闭和创建。

对于连接池的使用依赖于你是如何配置连接池,如果使用不当会导致下面问题:

大量的连接空闲,导致额外的工作和延迟。
连接数据库的连接过多导致错误。
连接阻塞。
连接池有超过十个或者更多的死连接,限制就是10次重连。

大多数时候,如何使用sql.DB对连接的影响大过连接池配置的影响。这些具体问题我们会再使用sql.DB的时候逐一介绍。

掌握了database/sql关于数据库连接池管理内容,下一步则是使用这些连接,进行数据的交互操作啦。

连接池

只用sql.Open函数创建连接池,可是此时只是初始化了连接池,并没有创建任何连接。连接创建都是惰性的,只有当你真正使用到连接的时候,连接池才会创建连接。连接池很重要,它直接影响着你的程序行为。

连接池的工作原来却相当简单。当你的函数(例如Exec,Query)调用需要访问底层数据库的时候,函数首先会向连接池请求一个连接。如果连接池有空闲的连接,则返回给函数。否则连接池将会创建一个新的连接给函数。一旦连接给了函数,连接则归属于函数。函数执行完毕后,要不把连接所属权归还给连接池,要么传递给下一个需要连接的(Rows)对象,最后使用完连接的对象也会把连接释放回到连接池。

请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下:

db.Ping() 调用完毕后会马上把连接返回给连接池。
db.Exec() 调用完毕后会马上把连接返回给连接池,但是它返回的Result对象还保留这连接的引用,当后面的代码需要处理结果集的时候连接将会被重用。
db.Query() 调用完毕后会将连接传递给sql.Rows类型,当然后者迭代完毕或者显示的调用.Clonse()方法后,连接将会被释放回到连接池。
db.QueryRow()调用完毕后会将连接传递给sql.Row类型,当.Scan()方法调用之后把连接释放回到连接池。
db.Begin() 调用完毕后将连接传递给sql.Tx类型对象,当.Commit()或.Rollback()方法调用后释放连接。

因为每一个连接都是惰性创建的,如何验证sql.Open调用之后,sql.DB对象可用呢?通常使用db.Ping()方法初始化:

`