wanshenmean
2026-03-06 aefdecd0aa3226b7d00d1dc764241b82658b3be8
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/HybridCacheService.cs
@@ -573,6 +573,104 @@
            }
        }
        /// <summary>
        /// 安全更新:仅当内存缓存中的值与expectedVersion匹配时才更新
        /// 防止并发写入时旧值覆盖新值
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="newValue">新值</param>
        /// <param name="expectedVersion">期望的版本(通常是旧对象的哈希值或时间戳)</param>
        /// <param name="versionExtractor">从对象提取版本号的函数</param>
        /// <param name="expireSeconds">过期时间</param>
        /// <returns>是否更新成功</returns>
        public bool TrySafeUpdate<T>(
            string key,
            T newValue,
            object? expectedVersion,
            Func<T, object?> versionExtractor,
            int expireSeconds = -1) where T : class
        {
            var fullKey = BuildKey(key);
            // 从Redis获取当前值
            string? existingJson = null;
            T? existingValue = default;
            if (RedisAvailable)
            {
                try
                {
                    var value = _connectionManager.GetDatabase().StringGet(fullKey);
                    if (!value.IsNullOrEmpty)
                    {
                        existingJson = value.ToString();
                        existingValue = _serializer.Deserialize<T>(existingJson);
                    }
                }
                catch { }
            }
            // 如果Redis不可用,从内存缓存获取
            if (existingValue == null && _options.EnableL1Cache)
            {
                if (_memoryCache.TryGetValue(fullKey, out string? cached) && cached != null)
                {
                    existingValue = _serializer.Deserialize<T>(cached);
                    existingJson = cached;
                }
                else
                {
                    return false;
                }
            }
            // 检查版本是否匹配
            if (existingValue != null)
            {
                var currentVersion = versionExtractor(existingValue);
                if (!Equals(currentVersion, expectedVersion))
                {
                    _logger.LogWarning("TrySafeUpdate版本不匹配, key={Key}, expected={Expected}, current={Current}",
                        key, expectedVersion, currentVersion);
                    return false; // 版本不匹配,拒绝更新
                }
            }
            // 版本匹配,执行更新
            var newJson = _serializer.Serialize(newValue);
            // 先写入Redis
            if (RedisAvailable)
            {
                try
                {
                    var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
                    if (!_connectionManager.GetDatabase().StringSet(fullKey, newJson, expiry))
                    {
                        _logger.LogWarning("Redis TrySafeUpdate写入失败, key={Key}", key);
                        return _options.FallbackToMemory && _options.EnableL1Cache;
                    }
                    else
                    {
                        _logger.LogInformation("Redis TrySafeUpdate写入成功, key={Key}", key);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "Redis TrySafeUpdate写入失败, key={Key}", key);
                    return _options.FallbackToMemory && _options.EnableL1Cache;
                }
            }
            // 更新内存缓存
            if (_options.EnableL1Cache)
            {
                SetMemoryCache(fullKey, newJson, expireSeconds, false);
            }
            return true;
        }
        public object? Get(Type type, string key)
        {
            var fullKey = BuildKey(key);