緩存通常用於提高數據訪問的效率。一般來説,緩存讀取和寫入的邏輯遵循“先從緩存取,取不到再從數據庫獲取並寫回緩存”的原則。為了避免多個線程同時修改緩存數據,我們需要加鎖來保證數據一致性。
邏輯概述
- 讀取緩存:緩存命中直接返回。
- 緩存未命中:加鎖,然後再次讀取緩存,緩存命中直接返回。
- 緩存還是未命中:執行數據庫查詢並更新緩存。
- 返回數據。
代碼大致這樣寫
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();
}
}
}