事務四大特性 (ACID)
| 特性 | 含義 | MySQL 實現 |
| 原子性 | 操作要麼全做,要麼全不做 | Undo Log 回滾 |
| 一致性 | 事務前後數據完整性約束保持 | 約束檢查 + 原子性/隔離性/持久性保障 |
| 隔離性 | 並發事務互不干擾 | MVCC + 鎖 (RR 默認) |
| 持久性 | 提交後永久生效,不怕崩潰 | Redo Log (WAL) + 雙寫緩衝 |
事務控制語句
-- 1. 顯式啟動
START TRANSACTION; -- 或 BEGIN; BEGIN WORK;
-- 2. 業務 SQL
UPDATE account SET balance = balance - 500 WHERE user = '李三';
UPDATE account SET balance = balance + 500 WHERE user = '趙四';
-- 3. 提交 / 回滾
COMMIT; -- 持久化
ROLLBACK; -- 撤銷所有變更
自動提交模式
DELIMITER //
CREATE PROCEDURE transfer(
IN from_user VARCHAR(50),
IN to_user VARCHAR(50),
IN amount DECIMAL(10,2)
)
BEGIN
DECLARE from_balance DECIMAL(10,2);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL; -- 重新拋出異常給調用者
END;
START TRANSACTION;
-- 1. 悲觀鎖檢查餘額
SELECT balance INTO from_balance
FROM account WHERE user = from_user FOR UPDATE;
IF from_balance < amount THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '餘額不足';
END IF;
-- 2. 扣款/入賬
UPDATE account SET balance = balance - amount WHERE user = from_user;
UPDATE account SET balance = balance + amount WHERE user = to_user;
-- 3. 記錄流水
INSERT INTO transfer_log (from_user, to_user, amount, status, create_time)
VALUES (from_user, to_user, amount, 'SUCCESS', NOW());
COMMIT;
END//
DELIMITER ;
事務隔離級別
| 級別 | 髒讀 | 不可重複讀 | 幻讀 | MySQL 默認 |
| READ UNCOMMITTED | 可能 | 可能 | 可能 | |
| READ COMMITTED | 不可 | 可能 | 可能 | |
| REPEATABLE READ | 不可 | 不可 | 可能 (InnoDB 間隙鎖解決) | ✓ |
| SERIALIZABLE | 不可 | 不可 | 不可 | |
保存點(大事務中分段回滾)
START TRANSACTION;
UPDATE ...;
SAVEPOINT sp1;
UPDATE ...;
IF error THEN ROLLBACK TO sp1; END IF;
COMMIT;
避坑指南
- 引擎必須支持事務:
InnoDB / BDB,MyISAM 不支持。
- 長事務危害大:Undo Log 膨脹、鎖持久、主從延遲、回滾耗時,**業務拆分小事務**。
- 異常必須回滾:應用層捕獲異常 →
rollback(),否則連接歸池時隱式提交髒數據。
- 死鎖自動檢測:InnoDB 會自動回滾代價較小的事務,應用層捕獲
Lock wait timeout exceeded / Deadlock found 重試。