gorm使用事务并发情况下切有最大mysql连接数限制的情况下的BUG,踩坑了
你看到的这个文章来自于http://www.cnblogs.com/ayanmw
现象
服务器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事务的踩坑用法,知道为什么这么写更重要.
转载请注明出处:http://www.cnblogs.com/ayanmw 我会很高兴的!
------------------------------------------------------------------------------------------------
一定要专业!本博客定位于 ,C语言,C++语言,Java语言,Android开发和少量的Web开发,之前是做Web开发的,其实就是ASP维护,发现EasyASP这个好框架,对前端后端数据库 都很感觉亲切啊。. linux,总之后台开发多一点。以后也愿意学习 cocos2d-x 游戏客户端的开发。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2022-03-14 解决 win10 连接VPN失败: 不能建立到远程计算机的连接你可能需要更改此连接的网络设置