调用Post API时学生与爱好关联请求卡住,求技术排查
排查Post API调用CreateStudentHobby时请求卡住的问题
问题现象
调用处理学生与爱好关联关系的Post API时,请求出现卡住情况:
相关代码
以下是学生创建接口的核心实现代码:
func (s StudentServiceImpl) Create(ctx context.Context, request web.StudentCreateRequest) web.StudentResponse { err := s.Validate.Struct(request) helper.PanicIfError(err) tx, err := s.DB.Begin() helper.PanicIfError(err) defer helper.CommitOrRollback(tx) major, isExistMajor := s.MajorService.FindByMajorName(ctx, request.Major) //fmt.Println(isExistMajor) if isExistMajor == false { major = s.MajorService.Create(ctx, request.Major) } student := domain.Student{ Name: request.Name, Age: request.Age, Gender: request.Gender, CreatedAt: time.DateTime, Major: major, } student = s.StudentRepository.Save(ctx, tx, student) studentId := student.Id hobbies := s.HobbyService.Creates(ctx, request.Hobbies) fmt.Println(hobbies, studentId) for i := 0; i < len(hobbies); i++ { // todo this below service bug stuck in sending request... //s.HobbyService.CreateStudentHobby(ctx, studentId, hobbies[i].Id) } return helper.ToStudentResponse(student) }
对应仓库代码位置:service/student_service_impl.go#L39
排查方向及修复建议
1. 跨事务的数据库阻塞(最可能原因)
当前代码开启了全局事务tx,但调用CreateStudentHobby时未传递该事务对象。如果CreateStudentHobby使用独立数据库连接操作关联表:
- 主事务未提交前,刚插入的学生记录仅在当前事务内可见,
CreateStudentHobby的独立事务无法读取该记录; - 若
student_hobby表的student_id字段设置了外键关联students表,数据库会因外键检查等待主事务提交,直接导致请求卡住。
修复方式:
修改CreateStudentHobby方法,让它接收主事务tx参数,将关联操作纳入同一事务:
// 循环内调用修改为: s.HobbyService.CreateStudentHobby(ctx, tx, studentId, hobbies[i].Id)
同时调整HobbyService.CreateStudentHobby的实现,使用传入的事务执行数据库操作。
2. 数据库连接池耗尽
循环调用CreateStudentHobby时,若每次调用都创建新数据库连接,请求量较大时可能耗尽连接池,导致后续操作等待空闲连接而阻塞。
修复方式:
- 确保数据库操作复用连接池;
- 改为批量插入学生-爱好关联记录,减少数据库调用次数。
3. 上下文未正确处理
检查CreateStudentHobby内部是否监听了ctx的Done()信号,若上下文被取消/超时但未处理,可能导致操作无限阻塞。
修复方式:
在CreateStudentHobby的数据库操作中传递ctx,确保操作能响应上下文的取消信号。
4. 内部死循环或耗时操作
检查CreateStudentHobby的实现是否存在死循环、未处理的错误,或者调用了其他耗时且未设置超时的服务。
内容的提问来源于stack exchange,提问作者Noranekoit
相关产品推荐
相关产品推荐

