Transaction 交易 (SQL Transaction)
Transaction(交易)是資料庫中一組操作的集合,這些操作要嘛全部成功執行,要嘛全部不執行。這確保了資料的一致性和完整性。
舉例來說,銀行轉帳時需要從 A 帳戶扣款,再存入 B 帳戶。如果扣款成功但存入失敗,就會造成資料不一致。使用交易可以確保這兩個操作要嘛都成功,要嘛都失敗。
交易的 ACID 特性
- Atomicity(原子性):交易中的所有操作是不可分割的,要嘛全部成功,要嘛全部失敗
- Consistency(一致性):交易完成後,資料庫必須保持一致的狀態
- Isolation(隔離性):多個交易同時執行時,彼此之間不會互相影響
- Durability(持久性):交易一旦提交,對資料的變更就是永久的
交易的基本語法
開始交易
-- SQL Server / PostgreSQL
BEGIN TRANSACTION;
-- MySQL
START TRANSACTION;
提交交易 (COMMIT)
當所有操作都成功執行後,使用 COMMIT 來確認並儲存變更:
COMMIT;
回滾交易 (ROLLBACK)
如果發生錯誤,使用 ROLLBACK 來取消所有變更,將資料還原到交易開始前的狀態:
ROLLBACK;
實際範例
以下是一個銀行轉帳的例子:
-- 開始交易
START TRANSACTION;
-- 從帳戶 A 扣款 1000 元
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';
-- 存入帳戶 B
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 'B';
-- 確認所有操作成功,提交交易
COMMIT;
如果在執行過程中發生錯誤:
START TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';
-- 假設這裡發生錯誤...
-- 回滾交易,取消所有變更
ROLLBACK;
SAVEPOINT 儲存點
SAVEPOINT 讓你可以在交易中設定一個還原點,發生錯誤時可以只回滾到這個點,而不是回滾整個交易:
START TRANSACTION;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 'A';
-- 設定儲存點
SAVEPOINT sp1;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 'A';
-- 如果第二次扣款有問題,只回滾到 sp1
ROLLBACK TO SAVEPOINT sp1;
-- 第一次扣款仍然有效,提交交易
COMMIT;
刪除儲存點(不回滾):
RELEASE SAVEPOINT sp1;
自動提交模式
大多數資料庫預設都是「自動提交」(Auto-commit) 模式,每條 SQL 語句執行後會自動提交。
關閉自動提交(MySQL):
SET autocommit = 0;
-- 或
SET autocommit = OFF;
開啟自動提交(MySQL):
SET autocommit = 1;
-- 或
SET autocommit = ON;
使用 START TRANSACTION 或 BEGIN 開始交易時,會暫時停用自動提交,直到 COMMIT 或 ROLLBACK 為止。