fix(fr007-cache): 直查命中失效快照+去冗余排序+重载失败保旧快照防重试风暴

- EodPriceQueryService.TryGetPrice: FR007 快照 miss 直查库命中后 Invalidate,
  下次访问整表重载回 O(1),否则该键 TTL 窗口内每次读取都退化为点查
- 移除点查多余的 OrderByDescending(主键等值查询取首行即可)
- Fr007FixingCache.EnsureFresh: 重载失败(DB抖动)保留旧快照不抛并重置TTL时钟
  ——历史定盘不可变旧值依旧正确,同时防重试风暴;版本失效路径不受TTL掩盖
- 补两测试: 重载失败保快照窗口内不重试 / 首次装载失败miss不抛窗口内不重试
This commit is contained in:
hjhan
2026-08-18 09:33:28 +08:00
parent e219bdae18
commit 7a5089555d
3 changed files with 56 additions and 6 deletions
@@ -80,11 +80,24 @@ namespace YLErp.Modules.DataProviderModule
lock (_reloadLock)
{
if (IsFresh()) return;
var snap = LoadSnapshot();
Volatile.Write(ref _snapshot, snap);
Volatile.Write(ref _loaded, true);
Volatile.Write(ref _loadedAt, NowTicks());
Volatile.Write(ref _snapVersion, Volatile.Read(ref _writeVersion));
try
{
var snap = LoadSnapshot();
Volatile.Write(ref _snapshot, snap);
Volatile.Write(ref _loaded, true);
Volatile.Write(ref _loadedAt, NowTicks());
Volatile.Write(ref _snapVersion, Volatile.Read(ref _writeVersion));
}
catch (Exception ex)
{
// 重载失败(如DB抖动):保留旧快照并重置TTL时钟——历史定盘不可变,旧值依旧正确;
// 同时防止每次读取都重试全表SELECT(重试风暴)。不抛:命中继续走旧快照,
// miss照旧回退直查库,新数据取不到仍会在直查处响亮报错。
// 注:版本失效(Invalidate)后的重载失败不会被TTL掩盖——版本不相等会持续重试直到成功。
Volatile.Write(ref _loaded, true);
Volatile.Write(ref _loadedAt, NowTicks());
LogFactory.GetLogger("Fr007FixingCache").Error("FR007定盘缓存重载失败,沿用旧快照", ex);
}
}
}