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请求太多,会阻塞,这才引入了连接池