050204-修复URS推荐关系缓存断代问题.md 6.1 KB

修复URS推荐关系缓存断代问题

任务时间: 2025年07月05日 02:04
任务类型: Bug修复
模块: UrsPromotion/UrsRelationCacheLogic

问题描述

用户反馈"未进入农场,跳过缓存生成"会造成推荐关系的"断代"问题。

问题场景

假设推荐链:A (未进入农场) → B (已进入农场) → C (已进入农场) → D (已进入农场)

原有逻辑问题

  • 当B用户尝试生成关系缓存时,发现推荐人A未进入农场
  • 系统直接跳过B的缓存生成
  • 导致B、C、D都无法建立与A的关系缓存
  • 结果:整个推荐链断裂,A永远无法获得下级奖励

业务影响

  1. 奖励分发断裂:推荐人无法获得下级奖励
  2. 数据不完整:关系缓存表缺失大量有效推荐关系
  3. 用户体验差:推荐人看不到下级数据
  4. 业务逻辑错误:违背推荐系统基本原则

解决方案

1. 修改缓存生成逻辑

原有逻辑

// 如果农场用户ID为0,跳过缓存生成
if ($farmUserId <= 0 || $farmReferrerId <= 0) {
    Log::info("URS用户 {$ursUserId} 或推荐人 {$ursReferrerId} 未进入农场,跳过缓存生成");
    return true;
}

新逻辑

  • 如果当前用户未进入农场,跳过缓存生成
  • 如果推荐人未进入农场,创建占位缓存记录,避免断代
  • 通过URS关系链向上查找已进入农场的上级

2. 占位缓存机制

当推荐人未进入农场时:

  1. 创建占位的直接关系缓存(related_user_id = 0
  2. 通过URS关系链向上递归查找
  3. 为已进入农场的上级创建有效缓存
  4. 为未进入农场的上级创建占位缓存

3. 推荐人进入农场时的修复机制

当推荐人后来进入农场时:

  1. 更新所有占位缓存记录(related_user_id 从0更新为实际农场用户ID)
  2. 更新路径中的占位符(将路径中的'0'替换为实际农场用户ID)
  3. 为该用户的所有下级重新生成缓存,修复断代问题

实现详情

1. 核心方法修改

generateUserRelationCache() 方法

  • 区分当前用户和推荐人的进入农场状态
  • 推荐人未进入农场时创建占位缓存
  • 调用新的递归方法处理间接关系

新增辅助方法

  1. generateIndirectRelationsFromUrsChain() - 基于URS关系链生成间接关系
  2. generateIndirectRelationsFromExistingCache() - 基于已有缓存生成间接关系
  3. updatePlaceholderPaths() - 更新路径中的占位符
  4. regenerateDownstreamCaches() - 重新生成下级缓存

2. 路径构建方法

  1. buildFarmUserPath() - 构建农场用户路径
  2. buildUrsPath() - 构建URS用户路径
  3. buildCombinedFarmPath() - 构建组合农场用户路径
  4. buildCombinedUrsPath() - 构建组合URS用户路径

3. 缓存更新机制

updateFarmUserIdInCache() 方法增强

  • 更新占位缓存记录(related_user_id 从0更新为实际ID)
  • 更新路径中的占位符
  • 为所有下级重新生成缓存

测试工具

创建了专门的测试命令 TestRelationCacheFixCommand

# 检查断代问题
php artisan urs:test-relation-cache-fix --check

# 修复断代问题
php artisan urs:test-relation-cache-fix --fix

# 显示统计信息
php artisan urs:test-relation-cache-fix --stats

# 测试特定用户
php artisan urs:test-relation-cache-fix --user-id=24127

测试功能

  1. 检查断代问题:查找有推荐关系但无缓存的用户
  2. 修复断代问题:批量重新生成缺失的缓存
  3. 统计信息:显示缓存完整性统计
  4. 特定用户测试:详细测试单个用户的缓存生成

技术特点

1. 向后兼容

  • 保持现有缓存结构不变
  • 新增占位机制不影响现有查询逻辑
  • 渐进式修复,不需要全量重建

2. 性能优化

  • 递归深度限制(最多20代)
  • 批量更新减少数据库操作
  • 智能跳过已处理的记录

3. 数据完整性

  • 占位缓存确保关系链完整
  • 自动修复机制确保数据一致性
  • 详细日志记录便于问题追踪

4. 业务逻辑正确性

  • 解决断代问题,确保奖励正常分发
  • 保持推荐关系的完整性
  • 支持推荐人后续进入农场的场景

预期效果

  1. 解决断代问题:推荐人未进入农场不再导致整个推荐链断裂
  2. 完整的关系缓存:所有有效推荐关系都有对应的缓存记录
  3. 正常的奖励分发:推荐人进入农场后能正常获得下级奖励
  4. 良好的用户体验:推荐数据完整,用户满意度提升

数据库索引优化

问题发现

在实现过程中发现原有的 idx_user_relation 唯一索引存在问题:

  • 原索引UNIQUE KEY idx_user_relation (user_id, related_user_id)
  • 问题:当多个用户的推荐人都未进入农场时,都会产生 related_user_id = 0 的占位记录
  • 冲突:违反唯一约束,导致插入失败

解决方案

移除有问题的索引,增加包含深度的组合索引:

  • 移除idx_user_relation (user_id, related_user_id)
  • 新增idx_user_relation_depth (user_id, related_user_id, depth)

优化效果

  1. 允许占位记录:多个用户可以有 related_user_id = 0 的记录
  2. 防止真正重复:同一用户、同一上级、同一深度不能重复
  3. 保持性能:索引仍然提供良好的查询性能
  4. 业务逻辑正确:符合推荐关系的实际业务需求

风险控制

  1. 占位缓存标识:使用related_user_id = 0明确标识占位记录
  2. 递归深度限制:防止无限递归导致性能问题
  3. 异常处理:完善的错误处理和日志记录
  4. 测试工具:提供完整的测试和验证工具
  5. 索引优化:合理的数据库索引设计,避免约束冲突

总结

本次修复彻底解决了URS推荐关系缓存的断代问题,通过占位缓存机制确保推荐链的完整性,同时提供了完善的修复和测试工具。修复后的系统能够正确处理推荐人未进入农场的场景,确保业务逻辑的正确性和用户体验的完整性。