马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
缓存通常用于进步数据访问的服从。一样平常来说,缓存读取和写入的逻辑遵照“先从缓存取,取不到再从数据库获取并写回缓存”的原则。为了制止多个线程同时修改缓存数据,我们须要加锁来包管数据同等性。
逻辑概述
- 读取缓存:缓存掷中直接返回。
- 缓存未掷中:加锁,然后再次读取缓存,缓存掷中直接返回。
- 缓存照旧未掷中:实验数据库查询并更新缓存。
- 返回数据。
代码大抵如许写
- 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();
- }
- }
- }
复制代码 关键是缓存在锁前和锁后都要读一次,为了镌汰多个线程都在等候锁的环境,同时进来查询数据库写缓存。
分布式环境下会更复杂一些
免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金. |