页首Html代码

返回顶部

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 我会很高兴的!

posted @   ayanmw  阅读(181)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2022-03-14 解决 win10 连接VPN失败: 不能建立到远程计算机的连接你可能需要更改此连接的网络设置

页脚Html代码

点击右上角即可分享
微信分享提示