gorm连接池

连接泄露问题

golang mysql驱动和连接

基本的类都在go/src/database/sql/目录下

其中,driver/driver.go中是一些基本接口,

而实现类根据连接的数据库而定,比如,mysql,那么会有相应的驱动类

https://github.com/go-sql-driver/mysql driver.go中,初始方法init是连接驱动,或者说是注册驱动:

这时候还未连接数据库

真正连接数据路是driver open方法

上层的gorm 连接的时候,也是通过driver来连接的

调用的顺序为(以启动时为例):

1、gorm调用golang的open方法

2、golang调用内部的字方法sql.go func OpenDB(c driver.Connector) *DB

3、OpenDB内部调用sql.go中connectionOpener

4、接着调用openNewConnection方法

5、调用内部的Connect方法方法

6、再调用mysql driver中的Open方法,这样就建立了一个连接,

7、apc项目中如果建立连接,则保存db信息,这个db信息可以看做是一个数据源以及一个schema, 如果config.toml有多个数据源,就会有一个map,key是mysql.**中.后面的名称,value就是db信息

golang mysql连接

上面是启动时连接数据库时的操作,其实每次一个sql请求,如果需要新建连接,跟上面的流程一样,最终都会调用sql.go中ci, err := db.connector.Connect(ctx)的Connct方法,这个方法是driver.go的interfface,已经在sql.go中实现了,最终还是会调用mysql driver的Open方法,也就是携带dsn信息新建连接。

其实启动时,要建立连接,我的理解是有多个原因:

1、先进行校验,不然启动时都不知道数据库是否有问题,是否有连接权限

2、保存一些参数,设置一些连接池参数

其实可以类比,java进行裸jdbc进行查询数据库,每次都会进行如下的操作:

这个可以写到初始化方法中,别的地方的请求都会复用这个conn,但是对于生产和并发情况下就不太适用,因为一个conn肯定不够用的,sql请求太多,会阻塞,这才引入了连接池