gorm 的使用上的坑

   db := database.GetDB(ctx)

func (a *RuleTarget) DelSystemRuleTargets(
    ctx context.Context,
    targets []*pbWeb.RuleTarget,
) (successCount int32, err error) {
    for _, target := range targets {

        // 注意如果是uid层面的删除,要级联删除cid和aid的数据
        if fflag.IsSwitchOn(ctx, fflag.FlagSystemRuleAllRalated) {
            log.ErrorContextf(ctx, "begin delete")
            db = db.Where("rule_id = ?", 0).Where("account_id = ?", target.AccountId).
                Where("status = ?", 0)
            if target.CampaignId != 0 {
                // 对cid进行删除
                db = db.Where("campaign_id = ?", target.CampaignId)
            }
            err = db.Delete(RuleTarget{}).Error
        } else {
            err = db.Where(map[string]interface{}{
                "rule_id":     0,
                "account_id":  target.AccountId,
                "campaign_id": target.CampaignId,
                "adgroup_id":  target.AdgroupId,
            }).Delete(RuleTarget{}).Error
        }
        if err != nil {
            log.ErrorContextf(ctx, "RuleTarget.DelSystemRuleTargets() Error: %s", err.Error())
            continue
        } else {
            successCount++
        }

    }

    return successCount, nil
}

这里db = xx 语句执行了多次,因此这里gorm将查询条件放在了db中。结果就是在循环中下次执行的时候,db中的数据并没有清除掉。带上了上次的执行条件。例如:

第一次:

 UPDATE `rule_targets` SET `deleted_at`='2021-05-24 15:57:32'  WHERE `rule_targets`.`deleted_at` IS NULL AND ((rule_id = 0) AND (account_id = 172198) AND (status = 0))

第二次:

UPDATE `rule_targets` SET `deleted_at`='2021-05-24 15:57:32'  WHERE `rule_targets`.`deleted_at` IS NULL AND ((rule_id = 0) AND (account_id = 172198) AND (status = 0) AND (rule_id = 0) AND (account_id = 20458) AND (status = 0))

但是这么写就可以:

// 开启保护中状态
// 因为存在批量操作,这里对非一键托管状态的aid忽略掉
func (a *RuleTarget) OpenSystemRuleProtected(ctx context.Context, targets []*pbWeb.RuleTarget) int {
   // aid开启保护中,先删除,后增加这条记录(status = -1)
   successCount := 0
   systemRuleTargetsmap, err := a.getAidSystemRuleTarget(ctx, targets)
   if err != nil {
      log.ErrorContextf(ctx, "err in OpenSystemRuleProtected call getAidSystemRuleTarget:%v", err)
      return successCount
   }
   db := database.GetDB(ctx)
   for _, target := range targets {
      // 不属于一键托管中
      if systemRuleTargetsmap[target.AdgroupId] == 0 {
         successCount++
         continue
      }
      log.ErrorContextf(ctx, "begin delete")
      err := db.Where(map[string]interface{}{
         "rule_id":     0,
         "account_id":  target.AccountId,
         "campaign_id": target.CampaignId,
         "adgroup_id":  target.AdgroupId,
      }).Delete(RuleTarget{}).Error
      if err != nil {
         log.ErrorContextf(ctx, "del rule_target[%v]err:%v", target, err)
         continue
      }
      // ruleTargetModel := &RuleTarget{
      //     RuleID:     0,
      //     AccountID:  target.AccountId,
      //     CampaignID: target.CampaignId,
      //     AdGroupID:  target.AdgroupId,
      //     Status:     -1,
      // }
      // ruleTargetModel.setInstance(ruleTargetModel)
      // err = ruleTargetModel.Save(ctx)
      // if err != nil {
      //     log.ErrorContextf(ctx, "del rule_target[%v]err:%v", target, err)
      //     continue
      // }
      successCount++
   }
   return successCount
}

虽然也是在一个循环中执行同一个db变量,但是因为没有db = db.xxx语句,没有将ctx中放入查询条件,因此,每次循环执行是正常的额

实际修复方案:

for _, target := range targets {
   db := database.GetDB(ctx)
   // 注意如果是uid层面的删除,要级联删除cid和aid的数据
   if fflag.IsSwitchOn(ctx, fflag.FlagSystemRuleAllRalated) {
      db = db.Where("rule_id = ?", 0).Where("account_id = ?", target.AccountId).
         Where("status = ?", 0)
      if target.CampaignId != 0 {
         // 对cid进行删除
         db = db.Where("campaign_id = ?", target.CampaignId)
      }
      err = db.Delete(RuleTarget{}).Error
   } else {
      err = db.Where(map[string]interface{}{
         "rule_id":     0,
         "account_id":  target.AccountId,
         "campaign_id": target.CampaignId,
         "adgroup_id":  target.AdgroupId,
      }).Delete(RuleTarget{}).Error
   }
   if err != nil {
      log.ErrorContextf(ctx, "RuleTarget.DelSystemRuleTargets() Error: %s", err.Error())
      continue
   } else {
      successCount++
   }

}

就是吧   db := database.GetDB(ctx)放到循环内

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值