大家好,我是 31 歲愛講故事的小米,一個喜歡在通勤路上刷源碼、在深夜裏喝咖啡寫技術文章的大哥哥。

前兩天去面一家公司,本來以為是常規“扯扯項目、問問框架、聊聊八股”那種,卻沒想到面試官直接用一句:

“小米,聊聊事務吧。ACID 是什麼?説具體點。”

我當場一個激靈:這不是八股中的八股嗎?但面試嘛,不能只説術語,要講人話,還要講故事。

於是我端起喝了一半的美式,就像講武俠一樣,把“事務”講成一出江湖大戲。

這一講,面試官聽得直點頭,最後還説一句:“有意思,你這個解釋方式我第一次聽。”

所以今天,就把那套講故事的方式寫下來,給你做武功秘籍,不僅讓你理解,還能讓你在下一次面試時吊打法器。

第一章:ACID 是什麼?江湖規矩四大門派

我當時對面試官笑笑説:

“事務嘛?就像江湖中的‘四大門派’,想維護世界和平就必須守住四個規矩。”

這四個規矩就是:

  • A - Atomicity 原子性
  • C - Consistency 一致性
  • I - Isolation 隔離性
  • D - Durability 持久性

為了讓他聽懂,我開始講故事:

原子性:一刀到底,不分你我

原子性像是一個江湖殺手的規矩:

要麼成功一刀斃命,要麼收刀走人,不能砍一半卡住。

事務也是一樣:

  • 要麼全部執行成功
  • 要麼全部不執行

比如銀行轉賬:

  • A 扣 100 元
  • B 加 100 元

這兩件事必須成對出現。如果只扣不加?社會亂套了。

因此數據庫保證在任何異常情況下都能“自動回滾”,確保事務像一刀到底的武功。

一致性:江湖必須保持平衡

一致性像江湖的天道平衡:

不管發生什麼,一定要保持前後邏輯一致。

比如銀行轉賬前:

  • 總金額 = 1 萬

轉賬後:

  • 總金額仍舊 = 1 萬

不會憑空多錢,也不會憑空少錢。

數據庫通過約束、觸發器、外鍵、校驗等保證這個平衡。

隔離性:各練各的功,不互相干擾

我當場舉例:

假設你去銀行取錢,同時我也去銀行取錢。你在窗口操作,我在 App 上操作,我們兩個的事務不能互相干擾,否則肯定會出現:

  • 你看到的餘額被我修改
  • 我看到的餘額被你覆蓋

隔離性就是:

讓每個事務擁有獨立練功房間,不被其他事務干擾。

數據庫有 4 個隔離級別:

  • Read Uncommitted
  • Read Committed
  • Repeatable Read
  • Serializable

隔離性越高,越安全,但性能越低。這就是江湖中典型的“安全 vs 性能”兩難。

持久性:功練成了,誰也抹不掉

持久性就像練成了絕世神功,無論外界怎麼風雨飄搖,你的功力不會掉。

數據庫裏,事務只要提交成功:

  • 數據必須持久化
  • 即使斷電、宕機、服務器崩潰也不能丟

這就是 WAL 日誌、redo log、binlog、checkpoint 等的價值。

到這裏,面試官笑着點點頭:“不錯,有畫面感。”

第二章:Redis 事務?呵呵,它不姓 ACID,它姓 KISS(簡單粗暴)

Redis 為什麼火?就是因為它足夠 簡單 + 暴力 + 快。於是它在事務這件事上,也延續了“簡單到離譜”的路線。

我繼續講故事:

“Redis 的事務不像數據庫那樣是‘江湖大師’,更像街邊擼串小店:

要不要一次性把菜都烤完?行。

要不要幫你回滾?不行。

要不要隔離?嗯……我們這裏沒那玩意。”

面試官:“繼續説。”

於是我説:

第三章:Redis 支持隔離性嗎?不支持!

Redis 用的是單線程模型。

也就是説,一個事務在執行的時候:

Redis 沒法讓其他命令插隊,但也沒法提供真正的隔離級別。

細説:

  • Redis 的事務只是把命令收集起來
  • 等到 EXEC 時,一次性按順序執行
  • 但整個過程中,Redis 不會隔離讀寫,不會快照,不會鎖住數據

所以 Redis 沒有隔離性!

你甚至在事務執行前:

  • 看到的數據已經被別人改了
  • watch 的鍵被修改後,整個事務直接失敗

典型的“你別動,我做完再説”的模式。

第四章:Redis 事務保證原子性嗎?不保證!

這句我一説完,面試官立刻坐直。

因為很多人以為 Redis 的事務很強,其實不是。Redis 的事務是這樣:

  • Redis 只保證 EXEC 中的命令會連續執行,不會被其他客户端插隊
  • 但不保證全部成功,要失敗就會局部失敗

比如你執行:

Redis 事務其實沒你想的強?深扒它的三個致命短板_數據庫

結果:

  • SET a 成功
  • INCR b 報錯
  • SET c 成功

Redis 不會幫你回滾!不會!不會!不會!

這就是 Redis 事務最大的坑:它不具備原子性,只具備“順序性”。

第五章:Redis 支持回滾嗎?不支持!

我給面試官舉例:

“數據庫像是安全顧問,做錯事會幫你撤銷。

Redis 像是你那粗線條的好兄弟:

哥們我幫你做了,但做錯我也沒辦法。”

Redis 的哲學:

  • 錯誤命令不會導致整個事務失敗
  • 成功的命令不會被撤銷
  • Redis 從來不保證回滾

為什麼?因為 Redis 追求速度,回滾會拖慢性能。

第六章:那 Redis 事務有什麼用?

這也是很多面試官愛問的關鍵點。

Redis 事務適合:

  • 批量執行命令
  • 給多個命令增加“一起執行”的語義
  • 配合 WATCH 實現輕量級樂觀鎖
  • 保證不會被插隊(單線程)

但絕不適合:

  • 強一致
  • 強隔離
  • 強原子性
  • 金融系統、轉賬系統

第七章:Redis 事務的三種核心機制

面試官問:“那 Redis 事務到底有哪些實現方式?”

我直接給他畫三條線:

1、MULTI / EXEC / DISCARD —— Redis 原生事務機制

流程:

  1. WATCH key(可選)——監聽變化,相當於樂觀鎖
  2. MULTI —— 開啓事務
  3. 一堆命令排隊
  4. EXEC —— 執行
  5. DISCARD —— 放棄事務

缺點:

  • 沒有回滾
  • 沒有隔離
  • 執行出錯不會撤銷之前命令

2、WATCH —— 樂觀鎖

WATCH 就是:

“我盯着某幾個鍵,你要是敢改,我就直接放棄執行。”

適合解決:

  • 搶購
  • 庫存扣減
  • CAS 更新(Compare And Set)

但 WATCH 失敗後要自己重試。Redis 不會幫你。

3、Lua 腳本 —— 真正的“Redis 原子性之王”

我當時看着面試官説:

“如果你真的想在 Redis 中實現原子性,那你一定要用 Lua。”

因為:

  • Lua 腳本在 Redis 裏是原子執行
  • 期間不會有其他命令插隊
  • 執行要麼全部成功,要麼全部失敗(邏輯自己寫)
  • 可以用邏輯手動模擬回滾

Lua 才是 Redis 中真正的“事務神器”。

面試官直接點頭:“對,這點很重要。”

第八章:總結——你在面試中應該這樣説

為了讓你面試不翻車,這裏給你一段 最佳答案:

ACID:

  • 原子性:事務要麼全部成功,要麼全部失敗
  • 一致性:數據前後符合規則
  • 隔離性:多個事務互相隔離
  • 持久性:提交後的數據不能丟失

Redis 事務:

  • Redis 不支持嚴格意義上的隔離性
  • Redis 事務不保證原子性,執行中有命令失敗不會回滾
  • Redis 事務不支持回滾
  • Redis 事務機制主要包括:
  • MULTI / EXEC
  • WATCH(樂觀鎖)
  • Lua 腳本(唯一能保證原子性)

END

這就是我那天在面試現場講的一套故事型解釋方式。

面試官很滿意,因為:

  • 不只是背概念
  • 而是真正解釋了背後邏輯
  • 還能用故事讓面試官不困
  • 最重要——你講得和別人不一樣

希望你在下一次面試時,也能把事務講得像江湖一樣精彩。

我是小米,一個喜歡分享技術的31歲程序員。如果你喜歡我的文章,歡迎關注我的微信公眾號“軟件求生”,獲取更多技術乾貨!