feat(swap): FR007定盘整表快照缓存——预载全历史O(1)命中,miss不缓存,写侧失效+1min TTL兜底

数据形态:每工作日一行、发布后不变、全历史仅数千行 → 整表快照优于逐键缓存。
① Fr007FixingCache:首次访问批量SELECT全历史进字典,此后读取O(1)零查询;
   快照以引用替换发布(Volatile),读侧无撕裂,重载加锁去抖;
② 负缓存防线:miss(当日~11:15未发布/补录历史)永不进快照,TryGetPrice 回退直查库——
   否则发布后TTL窗口内仍查不到,上午平仓会一直用回退利率;
③ 写侧版本失效:SwapFlowService 新增/修改/删除 FR007 后 Invalidate,下次访问立即
   整表重载不等TTL;其余通用写入口(导入/复制/合成/直改库)靠TTL兜底,可见性≤1分钟;
④ TryGetPrice 仅 FR007 走缓存路由(全仓生产调用方仅 SwapDealService.TryGetFloatRate
   与 Fr007IndexFixer 两处,均定盘链),其他标的照旧直查,零影响;
⑤ YLErpDAL 增加 InternalsVisibleTo("UnitTestProject"),时钟/装载器测试接缝保持 internal。

验证:Fr007FixingCacheTest 5/5(预载命中/miss不缓存/写侧立即生效/TTL过期重载/稳态零重载);
GLMS20260817Fr007UnwindMorningTest 等内存套件 55/55 全绿。
This commit is contained in:
hjhan
2026-08-18 08:24:21 +08:00
parent a97476c4da
commit e219bdae18
5 changed files with 214 additions and 0 deletions
@@ -149,6 +149,12 @@ namespace YLErp.Modules.DataProviderModule
price = 0;
valueDate = valueDate.Date;
// FR007 走整表快照缓存(预载全历史,O(1) 命中零查询)。miss=行尚不存在(当日未发布/补录),
// 继续直查库兜底——miss 永不进快照(负缓存防线,详见 Fr007FixingCache 注释)。
if (underlyingCode == Fr007FixingCache.UnderlyingCode && Fr007FixingCache.TryGet(valueDate, out price))
return true;
using var db = DbContextFactory.GetYLDbContext();
var data = db.eod_commodity_future_price.Where(x => x.ValueDate == valueDate && x.UnderlyingCode == underlyingCode).OrderByDescending(o => o.ValueDate).FirstOrDefault();