diff --git a/YLErpDAL/Modules/RiskEngine/Helper/RiskCalendarHelper.cs b/YLErpDAL/Modules/RiskEngine/Helper/RiskCalendarHelper.cs
index 6a02e77a..5109aee0 100644
--- a/YLErpDAL/Modules/RiskEngine/Helper/RiskCalendarHelper.cs
+++ b/YLErpDAL/Modules/RiskEngine/Helper/RiskCalendarHelper.cs
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Runtime.CompilerServices;
using YLErp.BLL;
namespace YLErp.Modules.RiskEngine
@@ -13,6 +14,12 @@ namespace YLErp.Modules.RiskEngine
///
public static class RiskCalendarHelper
{
+ ///
+ /// 按当前风控执行使用的数据库上下文保存日历缓存,同一次风控检查内复用,数据库上下文释放后不阻止缓存被回收。
+ ///
+ private static readonly ConditionalWeakTable>> HolidayCaches =
+ new ConditionalWeakTable>>();
+
///
/// 获取指定日期的上一银行间交易日。
///
@@ -36,7 +43,8 @@ namespace YLErp.Modules.RiskEngine
if (dbContext == null)
throw new ArgumentNullException(nameof(dbContext));
- var holidayCache = new Dictionary>();
+ // 以本次风控检查的数据库上下文为缓存边界,避免不同规则重复读取和解析相同市场日历。
+ var holidayCache = HolidayCaches.GetOrCreateValue(dbContext);
var currentDate = date.Date.AddDays(-1);
// 最多向前查 370 天,既覆盖跨年和长假场景,也避免日历配置异常时出现无限循环。
@@ -60,11 +68,13 @@ namespace YLErp.Modules.RiskEngine
///
/// 当前风控执行使用的数据库上下文。
/// 日历年份。
- /// 单次查询过程内的年份级缓存,跨年查找时避免重复读取同一年日历。
+ /// 单次风控检查内按市场和年份共享的非交易日缓存。
/// 格式为 yyyy,MM,dd 的非交易日集合。
- private static HashSet GetHolidays(YLContext dbContext, int year, string country, string calendarName, Dictionary> holidayCache)
+ private static HashSet GetHolidays(YLContext dbContext, int year, string country, string calendarName, Dictionary> holidayCache)
{
- if (holidayCache.TryGetValue(year, out var holidays))
+ // 缓存需要同时区分市场和年份,避免银行间与交易所同一年日历相互串用。
+ var cacheKey = $"{country.ToUpperInvariant()}:{year}";
+ if (holidayCache.TryGetValue(cacheKey, out var holidays))
return holidays;
// 同一年可能存在多种市场日历,按规则对应的市场代码读取非交易日。
@@ -90,7 +100,7 @@ namespace YLErp.Modules.RiskEngine
}
holidays = new HashSet(holidayList ?? new List());
- holidayCache[year] = holidays;
+ holidayCache[cacheKey] = holidays;
return holidays;
}
}