Description
`func (a Article) Get(c *gin.Context) {
//app.NewResponse(c).ToErrorResponse(errcode.ServerError)
//return
params := &service.ArticleRequest{ID: convert.StrTo(c.Param("id")).MustUInt32()}
response := app.NewResponse(c)
ok, errs := app.BindAndValid(c, params)
if !ok {
global.Logger.Errorf(c, "app.BindAndValid errs: %v", errs)
response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
return
}
svc := service.New(c.Request.Context())
article, err := svc.GetArticle(params)
if err != nil {
global.Logger.Errorf(c, "svc.GetArticle err: %v", err)
response.ToErrorResponse(errcode.ErrorGetArticleFail)
return
}
response.ToResponse(article)
return
}`
这里article, err := svc.GetArticle(params)调用 svc.GetArticle函数,这个函数里面有三次查询,公共的是是一个db上下文,存在链式连接,会导致上下文污染,第一个查询的 where条件带入到了 第二个查询中了
`func (svc *Service) GetArticle(param *ArticleRequest) (*Article, error) {
article, err := svc.dao.GetArticle(param.ID, param.State)
if err != nil {
return nil, err
}
log.Println("article:", article)
articleTag, err := svc.dao.GetArticleTagByAID(article.ID)
log.Println("v:", err)
if err != nil {
return nil, err
}
log.Println("articleTag:", articleTag)
tag, err := svc.dao.GetTag(articleTag.TagID, model.STATE_OPEN)
if err != nil {
return nil, err
}
log.Println("Tag:", tag)
return &Article{
ID: article.ID,
Title: article.Title,
Desc: article.Desc,
Content: article.Content,
CoverImageUrl: article.CoverImageUrl,
State: article.State,
Tag: &tag,
}, nil
}`
我是 在每一个查询中都使用新的会话来隔绝,或者使用事务来隔绝
`func (a Article) Get(db *gorm.DB) (Article, error) {
article := &Article{}
err := db.Session(&gorm.Session{}).Where("id = ? AND state = ? AND is_del = ?", a.ID, a.State, 0).First(article).Error
if err != nil && err != gorm.ErrRecordNotFound {
return *article, err
}
return *article, nil
}`