Jeff的隨手筆記

學習當一個前端工程師

0%

『菜鳥的踩坑筆記』-當 Cache 遇上 Session

這是一個記錄我在工作上遇到的一些問題與解決的方法

問題的開始

最近在處理一個有關使用者登入相關功能的bug時,被一個知識盲區的問題困擾了非常久,只好去請教主管了,下面就是我的一些簡單的紀錄。

當時的程式碼是這樣的:

1
2
3
4
5
6
7
public static UserInfo RegisterUserSession(UserData userData)
{
var user = ConvertToUserInfo(userData);
HttpContext.Current.Cache["user_" + userData.Name] = user;
HttpContext.Current.Session["CurrentUser"] = user;
return user;
}

這段程式碼同時使用了 Cache 和 Session 來儲存使用者資訊。看起來似乎是為了提高效能,但實際上卻帶來了一些問題。

問題的發現

在debug的過程中,我發現了一個奇怪的問題:明明是同一個使用者,資料卻時不時會出現不一致的情況。當時的我很直覺地認為,一定是程式碼哪裡出錯了,導致舊的資料被寫回資料庫。

就這樣,我一直在反覆檢查每個寫入資料庫的程式碼,希望找到那個「可疑的片段」。直到我意識到在同一個問題上糾結太久後,才去找主管討論。

這時主管拋出了一個關鍵問題:「你有檢查過Web.config 裡的設定嗎?」

這個問題立刻打開了我的盲點,讓我意識到問題可能不在程式碼本身。經過檢查,果然發現了以下問題:

  1. 資料不一致

    • Session 中的資料被更新了,但 Cache 中的還是舊的
    • 造成不同地方讀取到的使用者資訊不同
  2. 更新邏輯不完整

    1
    2
    3
    4
    5
    6
    7
    8
    public static UserInfo UpdateUser(UserData userData)
    {
    var currentUser = GetCurrentUser();
    currentUser.Balance = userData.Balance;
    // ... 其他更新
    HttpContext.Current.Session["CurrentUser"] = currentUser; // 只更新了 Session
    return currentUser;
    }
    • 只更新了 Session,沒有更新 Cache
    • 導致資料不同步

正確的做法

經過討論後,我們決定移除 Cache 的使用,只使用 Session:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static UserInfo RegisterUserSession(UserData userData)
{
if (userData == null)
throw new ArgumentNullException(nameof(userData));

var user = ConvertToUserInfo(userData);
HttpContext.Current.Session["CurrentUser"] = user;
return user;
}

public static UserInfo GetCurrentUser()
{
return HttpContext.Current.Session["CurrentUser"] as UserInfo;
}

為什麼這樣做更好?

  1. 單一資料來源
    • 所有的使用者資訊都只從 Session 讀取
    • 避免資料不同步的問題
  2. 符合系統設計
    • 系統其他地方都只用 Session
    • 保持設計的一致性
  3. 更容易維護
    • 程式碼更簡單明瞭
    • 減少潛在的錯誤來源

學到的教訓

  1. 不要過度設計
    • 如果 Session 已經足夠用了,就不需要再加上 Cache
    • 有時候簡單的解決方案反而是最好的
  2. 保持一致性
    • 遵循系統既有的設計模式
    • 不要為了一時的想法而破壞系統的一致性
  3. 注意資料同步
    • 當同一份資料存在多個地方時,要特別注意資料同步的問題
    • 最好的方法是避免資料重複儲存

希望這個經驗分享能幫助到遇到類似問題的開發者!