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 為止。