现象
服务器pprof中的goroutines 很多,无法释放,肯定是异常.
代码
// 收到 请求上个赛季个人秘境赛季排行
func (this *MsgProc) MsgProc_PersonSecretLastRankReq(msg *protoMsg.PersonSecretLastRankReq) {
global.GetSrvInst().GetThreadGo().Go(func(ctx context.Context) {
global.GetSrvInst().GetMysqlConn().Transaction(func(tx *gorm.DB) error {
// 拿到当前数据
var mynode *protoMsg.PersonSecretRankMD
global.GetSrvInst().GetMysqlConn().Where("seasonid=? and pid=?", msg.SeasonID, msg.PID).Find(&mynode)
if mynode == nil || mynode.SeasonID == 0 || mynode.PID == 0 {
// 空数据
server.PostPlayerSrv(msg.PID, gcommon.ServerTypeLobby, &protoMsg.PersonSecretLastRankRet{
LastSeasonID: msg.SeasonID,
PID: msg.PID,
LastSeasonRank: 0,
})
return nil
}
server.PostPlayerSrv(msg.PID, gcommon.ServerTypeLobby, &protoMsg.PersonSecretLastRankRet{
LastSeasonID: msg.SeasonID,
PID: msg.PID,
LastSeasonRank: mynode.SeasonRank,
LastSeasonEndTime: mynode.UpdatedAt.Unix(),
})
return nil
})
})
}
结论
在gorm的transaction中, Begin会申请一个conn链接, 然后内部如果在获取新的Mysql Conn的话, 当conn达到maxNum的时候,就会卡住, transaction无法自动释放conn,进而导致雪崩,其他的代码想要调用mysql都会出现等待conn的死锁情况.
所以 在 transaction 的代码中, 要用 tx 对象,不要用新的对象.
ps: 这代码是同事写的,但是引以为戒. 顺便 get 到gorm事务的踩坑用法,知道为什么这么写更重要.
标签:PID,连接数,gorm,mynode,mysql,msg,protoMsg,BUG,conn From: https://www.cnblogs.com/ayanmw/p/18073622