我們之前在課程裡已經提過什麼是交易。再提醒一下,這就是一連串操作,必須當成一個整體來執行。就像你要做銀行轉帳一樣,這時候你會從一個帳戶扣錢,再把錢加到另一個帳戶。如果其中一個動作失敗(比如錢扣了但沒加進去),那就會超麻煩。這時候交易就派上用場啦。
交易要嘛就是全部完成,要嘛就是完全沒做。這就是「全有或全無」的原則。
BEGIN;
-- 在一個帳戶上減少餘額
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- 在另一個帳戶上增加餘額
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT; -- 套用變更
如果有什麼地方出錯,可以用 ROLLBACK 來還原變更。
什麼是交易的 ACID 特性
當我們在講 PostgreSQL(還有所有關聯式資料庫)裡的交易時,常常會提到 ACID 這個縮寫——這不是化學啦。ACID 代表 Atomicity(原子性)、Consistency(一致性)、Isolation(隔離性)、Durability(持久性)。這四個特性確保資料能安全、連貫又不會出奇怪狀況地被處理。
原子性(Atomicity)
交易要嘛整個做完,要嘛完全沒做。如果裡面有什麼出錯——全部都會還原。想像一下:你在轉帳,突然出錯——要嘛全部取消,要嘛就全部完成。沒有什麼「只做一半」的操作。
一致性(Consistency)
交易結束後,資料庫會保持正確、合理的狀態。所有規則、限制還有表格之間的關聯都要遵守。比如說,如果你不允許負餘額,有違規的交易就不會被存下來。
隔離性(Isolation)
只要一個交易還沒結束,其他交易就不應該看到它的中間資料。這是為了防止那種你看到「不確定」資料狀態的怪現象。想像一下,在網路商店裡錢已經扣了,但商品還沒加進訂單——這感覺很差對吧?
持久性(Durability)
如果交易成功結束,所有變更都一定會被保存下來。就算馬上停電——資料還是在資料庫裡。就像你按了「儲存」一樣,完全不用擔心東西會不見。
這四個特性,就是為什麼交易被認為是資料庫操作裡最可靠的機制。
交易應用場景範例
理論很重要,但交易真正的威力是在實際任務裡才看得出來。特別是跟錢有關、表格有關聯、或是要大規模變更時,交易就是不可或缺的工具。它們不只是讓你能做操作,更讓你做得安心,不怕資料遺失或讓資料庫變成「半殘」狀態。
這裡有幾個典型例子,交易真的能救你一命:
1. 處理付款
當客戶從一個帳戶轉錢到另一個帳戶時,交易可以保證錢不會莫名其妙消失:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
如果第一個帳戶的錢不夠,可以還原變更:
BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 1;
-- 哎呀,餘額變負的了!
ROLLBACK;
2. 更新有關聯的表格
想像一下,你要把學生的狀態改成「畢業」,同時在「畢業生」表格加一筆紀錄:
BEGIN;
UPDATE students SET status = 'graduated' WHERE student_id = 42;
INSERT INTO graduates (student_id, graduation_date) VALUES (42, '2023-06-10');
COMMIT;
如果其中一個操作失敗(比如 INSERT 出錯),資料庫會還原到原本的狀態。
3. 大量資料更新
交易很適合做大量更新,比如說:
BEGIN;
UPDATE orders SET status = 'completed' WHERE delivery_date < CURRENT_DATE;
COMMIT;
如果伺服器掛了,或你發現更新錯了,隨時都能還原!
交易操作指令
PostgreSQL 提供幾個關鍵指令:
BEGIN: 開始一個新的交易:BEGIN;COMMIT: 確認(儲存)這次交易裡所有變更:COMMIT;
ROLLBACK: 還原這次交易裡所有變更:
ROLLBACK;
完整流程範例
BEGIN;
-- 一些操作
UPDATE accounts SET balance = balance - 200 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 200 WHERE account_id = 2;
-- 決定還原變更
ROLLBACK;
-- 重新開始
BEGIN;
-- 一樣的操作,不過換個金額
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- 結束交易
COMMIT;
課本外的交易人生
網路商店。 很多平台都用交易來管理訂單和付款。比如說,只有付款成功訂單才會成立。如果有什麼出錯,訂單就會自動取消。
銀行系統。 交易保護你的錢不會因為突然停電而出問題。
交易歷史。 PostgreSQL 會保存 WAL(Write-Ahead Logging)日誌,讓你在系統故障時能還原資料。這就是讓交易這麼可靠的魔法啦。
下一堂課我們會更詳細講 BEGIN、COMMIT 和 ROLLBACK 這些指令,還有看看大量操作和用 SAVEPOINT 做部分還原的例子。下次見囉!
GO TO FULL VERSION