當我們談到 Transaction(交易)時,指的是一組不可分割的 SQL 操作。這些操作結果只能成功或失敗,以確保資料庫的一致性和完整性。Transaction 是資料庫操作中的一個「邏輯單位」,包含多個操作步驟。如果其中任何一個步驟失敗,整個 Transaction 會回滾(rollback),恢復到初始狀態。因此,我們可以將一組 SQL 操作包裝成一個完整的 Transaction,確保這些操作只能有兩種結果:成功或失敗。
讓我們先用一個情境來說明。Alice 和 Bob 在帳戶裡都有 1000 元,而 Alice 轉帳給 Bob 200 元,那麼一筆完整的「交易處理」會是這樣:
set autocommit = 0;
START TRANSACTION;
UPDATE balances SET balance = 800 WHERE account = "Alice";
UPDATE balances SET balance = 1200 WHERE account = "Bob";
COMMIT;
針對資料庫來說,一個成功的交易必須要符合 ACID 特性。ACID 代表:原子性 (Atomicity)、一致性(Consistency)、隔離性 (Isolation)、永續性 (Durabilily),他們可說是關聯式資料庫核心的特性。
例如 A 想要給 B 一百元,A 要從錢包拿出鈔票、B 要把鈔票收進錢包,若交易中途突然來了一陣風把鈔票吹走了,由於 B 沒有收到鈔票,所以交易失敗,此時就必須把鈔票放回 A 的錢包。
2. 一致性(Consistency):交易(Transaction)確保資料庫從一個一致的狀態轉換到另一個一致的狀態。這意味著在交易開始前和結束後,資料庫的完整性約束不會被破壞。換句話說,交易完成前後,資料必須始終符合 schema 的規範,包括資料格式、資料限制和資料關聯。
例如 A 想要給 B 一百元,如果 A 給的是新台幣,完成交易時 B 不能莫名其妙的拿到美金。
例如 A 跟 C 同時要給 B 一百元,在交易時大風吹走了其中一張鈔票。B 手上確實拿到一張一百元,但他不確定是從誰拿到的,而被吹走的鈔票又是屬於誰的。
例如 A 和 B 之間時常互相借錢,每次借錢都會寫下借據,並把借據拍下來上傳到像 Google Drive 這樣雲端硬碟備份。就算實體借據不見了,兩人都可以在雲端硬碟裡找到過去的紀錄。
假設我們要進行一個轉帳操作,從 Alice 的帳戶轉 200 元到 Bob 的帳戶:
SET autocommit = 0; -- 關閉自動提交模式
START TRANSACTION; -- 開始交易
UPDATE balances SET balance = balance - 200 WHERE account = 'Alice';
UPDATE balances SET balance = balance + 200 WHERE account = 'Bob';
COMMIT; -- 提交交易
ROLLBACK
來回滾交易:ROLLBACK; -- 回滾交易
在同一時間內,有大量的使用者或應用程式同時對資料庫進行讀取或寫入操作時,資料庫需要能夠有效地處理多個交易,以確保資料的一致性和完整性,同時保持高效能。
以下是一些常見的高併發情境: