使用gorm做服务端,遇到的问题。运行的一些api产生的数据库连接,一直不释放,导致服务运行久了,连接数一直增加,最后服务挂掉。
这个是初始化数据库连接
var SqlDB *sql.DB
func InitOracleDB() {
databaseURL := fmt.Sprintf(`user="%s" password="%s" connectString="%s:%s/%s"`,
global.AppConfig.Server.Oracle.Username,
global.AppConfig.Server.Oracle.Password,
global.AppConfig.Server.Oracle.Ip,
global.AppConfig.Server.Oracle.Port,
global.AppConfig.Server.Oracle.Service,
)
sqlDB, err := sql.Open("godror", databaseURL)
if err != nil {
log.Fatalln("数据库连接失败...,err:", err)
}
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(30)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
//sqlDB.SetConnMaxLifetime(time.Hour)
SqlDB = sqlDB
// 设置日志
db, err := gorm.Open(oracle.New(oracle.Config{Conn: sqlDB}), &gorm.Config{
Logger: gormLog(),
NamingStrategy: schema.NamingStrategy{
TablePrefix: "", // table name prefix, table for `User` would be `t_users`
SingularTable: true, // use singular table name, table for `User` would be `user` with this option enabled
},
})
if err != nil {
log.Fatalln("数据库连接失败...,err:", err)
}
if global.AppConfig.Server.Mode == "release" {
global.DB = db
} else {
global.DB = db.Debug()
}
}
补充今天对api进行逐一分析:发现问题在于gorm中的会话模式,会产生新的数据库连接,创建一个Session后每次执行sql的时候都会导致tcp连接数量的增加,而且等待很久也不释放,问下大家有没有好的解决方法?
执行删除不增加:
str := "delete from objs_attent where Id=123"
err := global.DB.Exec(str).Error
执行查询不增加:
str := `with a1 as (SELECT ObjId as id,ObjName as value from phar_define where UseState > 0 ) select id as "id",value as "value",'phar' as "type" from a1 where rownum<=10`
结构体直接查询不增加:
var selectList []po.DicSignKind
global.DB.Model(&po.DicSignKind{}).Find(&selectList)
执行关联,统计数量不增加:
var totalCount int64
sql2 := global.DB.
Model(&po.PharDefine{}).
Select("phar_define.ObjId,ObjCode,ObjName,dic_sign_kind.Name as Type,Sign,phar_define.RtuCode,phar_state.StateId as StateId,b.dept_name as OrganName,c.dept_name as ChannelName,phar_define.UseState,phar_define.Organ,Channel").
Joins("left join phar_state on phar_state.ObjId=phar_define.ObjId"). // 连接航标状态获取终端号
Joins("left join dic_sign_kind on phar_define.SignKind=dic_sign_kind.Code"). // 连接航标类型
Joins("left join sys_dept b on phar_define.Organ=b.dept_id").
Joins("left join sys_dept c on phar_define.Channel=c.dept_id")
sql2.Count(&totalCount).
Find(&result)
创建session并执行查询则会增加连接
sql= global.DB.Table("phar_state").Where("RtuCode != 0")
sql = sql.Session(&gorm.Session{PrepareStmt: true}) // 保存前面拼接的SQL条件
err =sql.Where("RtuCode != 0").Find(&result).Error
比如如何锁定新的连接并删除该连接,我尝试用
kdb,err:=sql.Statement.DB.DB() 或者kdb,err :=global.DB.DB()
然后kdb.Close()
但是测试发现都是删除的初始数据库连接,而不是Session执行产生的新连接