bindbox-game/.trae/documents/Fix Race Condition in Ichiban Strategy GrantReward.md
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

1.3 KiB

修复一番赏策略库存扣减竞态问题

经检查,internal/service/activity/strategy/ichiban.go 中的 GrantReward 方法存在严重的竞态条件风险。当前实现采用“先查询库存,再更新库存”的方式,在高并发下可能导致超卖。

修复计划

我将参照 default.goreward_grant.go 中的正确实现,对 ichiban.go 进行以下修改:

  1. 重构 GrantReward 方法
    • 移除原有的 First() 查询逻辑。
    • 改为使用乐观锁原子更新:
      • 查询条件增加 Quantity > 0
      • 使用 UpdateSimple 执行 Quantity - 1
    • 根据 RowsAffected 判断扣减是否成功。

预期代码变更

func (s *ichibanStrategy) GrantReward(ctx context.Context, userID int64, rewardID int64) error {
    // 使用乐观锁原子扣减库存
    result, err := s.write.ActivityRewardSettings.WithContext(ctx).Where(
        s.write.ActivityRewardSettings.ID.Eq(rewardID),
        s.write.ActivityRewardSettings.Quantity.Gt(0),
    ).UpdateSimple(s.write.ActivityRewardSettings.Quantity.Add(-1))
    
    if err != nil {
        return err
    }
    if result.RowsAffected == 0 {
        return errors.New("sold out or reward not found")
    }
    return nil
}

此修改将彻底解决库存扣减的并发安全问题。