事務是資料庫確保資料一致性的基本單位,特別在高併發、金融、訂單等核心業務中不可或缺。MySQL 透過 InnoDB 引擎提供完整的事務支援。本文系統整理事務的四大特性、控制語法、隔離級別、死鎖預防與效能調優實戰經驗。
事務由一組互相依賴的 SQL 語句組成,作為不可分割的邏輯工作單元:要麼全做,要麼全不做。若任一語句失敗,整個事務回滾,資料恢復到事務開始前狀態。
| 特性 | 英文 | 說明 |
|---|---|---|
| 原子性 | Atomicity | 事務是最小執行單元,不可再分。 |
| 一致性 | Consistency | 事務前後資料庫保持一致狀態(如轉帳雙方金額總和不變)。 |
| 隔離性 | Isolation | 並發事務互不干擾,中間狀態對其他事務不可見。 |
| 持久性 | Durability | 提交後的修改永久保存,即使系統崩潰也能恢復。 |
START TRANSACTION; -- 或 BEGIN / BEGIN WORK
-- SQL 語句群
COMMIT; -- 提交
ROLLBACK; -- 回滾
SET autocommit = 0; -- 關閉自動提交
-- 後續所有語句隸屬同一事務,直到 COMMIT/ROLLBACK
SET autocommit = 1; -- 開啟自動提交 (預設)
注意:DDL (CREATE/DROP/ALTER) 會隱式提交,無法納入事務;非事務表 (MyISAM) 操作無法回滾。
MySQL/InnoDB 預設 REPEATABLE READ,透過 MVCC (多版本並發控制) 實現。
| 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 備註 |
|---|---|---|---|---|
| READ UNCOMMITTED | 可能 | 可能 | 可能 | 極少用 |
| READ COMMITTED | 不可能 | 可能 | 可能 | Oracle 預設 |
| REPEATABLE READ | 不可能 | 不可能 | 可能 (InnoDB 透過 Gap Lock 解決) | MySQL 預設 |
| SERIALIZABLE | 不可能 | 不可能 | 不可能 | 最高隔離,效能最低 |
設定方式:SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
READ COMMITTED 可減少鎖衝突。SELECT ... FOR UPDATE 主動加鎖。SHOW ENGINE INNODB STATUS 分析死鎖日誌。COMMIT,減少 fsync 開銷。START TRANSACTION;
DELETE FROM userinfo WHERE user_id = 1001;
DELETE FROM mail WHERE user_id = 1001;
DELETE FROM article WHERE author_id = 1001;
-- 若任一失敗
ROLLBACK;
-- 全部成功
COMMIT;
function executeTransaction($pdo, array $sqls) {
$pdo->beginTransaction();
try {
foreach ($sqls as $sql) {
$pdo->exec($sql);
}
$pdo->commit();
return true;
} catch (Exception $e) {
$pdo->rollBack();
return false;
}
}
掌握事務精髓,配合合理的隔離級別與小事務設計,能構建高可靠、高併發的資料庫應用系統。