网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > .Net >

缓存读写代码逻辑的正确姿势

时间:2026-01-30 22:26

人气:

作者:admin

标签:

导读:缓存通常用于提高数据访问的效率。一般来说,缓存读取和写入的逻辑遵循“先从缓存取,取不到再从数据库获取并写回缓存”的原则。为了避免多个线程同时修改缓存数据,我们需要...

缓存通常用于提高数据访问的效率。一般来说,缓存读取和写入的逻辑遵循“先从缓存取,取不到再从数据库获取并写回缓存”的原则。为了避免多个线程同时修改缓存数据,我们需要加锁来保证数据一致性。

逻辑概述

  1. 读取缓存:缓存命中直接返回。
  2. 缓存未命中:加锁,然后再次读取缓存,缓存命中直接返回。
  3. 缓存还是未命中:执行数据库查询并更新缓存。
  4. 返回数据。

代码大致这样写

public class CacheService
{
    private readonly ICache _cache;
    private readonly IDatabase _database;
    private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

    public CacheService(ICache cache, IDatabase database)
    {
        _cache = cache;
        _database = database;
    }

    public string GetDataFromCacheOrDb(string key)
    {
        // 1. 尝试从缓存获取数据
        var data = _cache.Get(key);
        if (data != null)
        {
            return data;  // 缓存命中,直接返回
        }

        // 2. 如果缓存中没有,尝试加锁并获取数据
        _semaphore.Wait();

        try
        {
            // 再次检查缓存(可能另一个线程已经填充了缓存)
            data = _cache.Get(key);
            if (data != null)
            {
                return data;  // 缓存命中,直接返回
            }

            // 3. 从数据库获取数据
            data = _database.Query(key);

            // 4. 将数据写入缓存
            _cache.Set(key, data);

            return data;
        }
        finally
        {
            // 释放锁
            _semaphore.Release();
        }
    }
}

关键是缓存在锁前和锁后都要读一次,为了减少多个线程都在等待锁的情况,同时进来查询数据库写缓存。

分布式情况下会更复杂一些

作者:Rick Carter
出处:http://pains.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信