fix: 使用 SemaphoreSlim 串行化数据库写入

问题:
- 多个后台线程同时写入数据库缓存
- SqlSugar Singleton 连接冲突

修复:
- 添加静态 SemaphoreSlim(1, 1) 写入锁
- 所有数据库写入操作串行化
- 写入失败不影响主流程(内存缓存已生效)

流程:
1. 获取价格成功 → 写入内存缓存(ConcurrentDictionary,线程安全)
2. 后台线程排队等待写入锁
3. 串行写入数据库(避免连接冲突)
4. 写入失败只记录日志
This commit is contained in:
OpenClaw Agent 2026-03-24 10:46:40 +00:00
parent e78d560f60
commit f2105eeb3a

View File

@ -27,6 +27,9 @@ public class MarketDataService : IMarketDataService
// 静态 pending 请求字典(跨请求共享,防止并发请求同一股票)
private static readonly ConcurrentDictionary<string, Lazy<Task<MarketPriceResponse>>> _pendingPriceRequests = new();
// 静态写入锁(串行化数据库写入)
private static readonly SemaphoreSlim _writeLock = new(1, 1);
public MarketDataService(
ILogger<MarketDataService> logger,
@ -200,9 +203,10 @@ public class MarketDataService : IMarketDataService
ExpiredAt = expireAt
}, expireAt);
// 写入数据库缓存(Fire-and-Forget失败不影响主流程
// 写入数据库缓存(串行化,避免连接冲突
_ = Task.Run(async () =>
{
await _writeLock.WaitAsync();
try
{
await SavePriceCacheAsync(symbol, assetType, response, source);
@ -211,6 +215,10 @@ public class MarketDataService : IMarketDataService
{
_logger.LogWarning(ex, "[数据库缓存写入失败] Symbol={Symbol},忽略(内存缓存已生效)", symbol);
}
finally
{
_writeLock.Release();
}
});
return response;