MySQL 交易處理核心概念與實戰:ACID 四特性、autocommit 模式、顯式交易控制、DDL 隱式提交、行鎖機制、隔離級別、Python 連線池交易範本、相對更新避免競態。
| 特性 | 說明 | 轉帳例子 |
|---|---|---|
| 原子性 | 不可分割的最小單元 | 扣款+入帳要麼全成要麼全失敗 |
| 一致性 | 從一致狀態轉換到一致狀態 | 總金額守恆,無憑空增減 |
| 隔離性 | 並發交易互不干擾 | 轉帳未提交前,其他交易看不到中間狀態 |
| 持久性 | 提交後永久保存,耐故障 | 系統崩潰重啟後帳目正確 |
CREATE TABLE t (...) ENGINE=InnoDB;
-- MyISAM 不支援交易
autocommit=ON:每句 SQL 即時提交SET autocommit=0(僅當前連線生效,斷線重連恢復預設)SELECT @@autocommitSTART TRANSACTION;
UPDATE account SET balance=balance-100 WHERE id=1;
UPDATE account SET balance=balance+100 WHERE id=2;
COMMIT; -- 或 ROLLBACK;
SET autocommit=0;
UPDATE account SET balance=balance-100 WHERE id=1;
UPDATE account SET balance=balance+100 WHERE id=2;
COMMIT; -- 此處才真正提交
-- 下一筆 SQL 自動開啟新交易
START TRANSACTION;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (i INT); -- 這裡會自動 COMMIT 前面的 INSERT
INSERT INTO t1 VALUES (2);
ROLLBACK; -- 只能回滾第二個 INSERT,第一個已提交、t2 已建立
受影響語句:CREATE/ALTER/DROP DATABASE/TABLE、TRUNCATE、LOCK/UNLOCK TABLES、SET AUTOCOMMIT 等。
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='pass', db='dbname')
try:
with conn.cursor() as cur:
cur.execute('SET autocommit=0')
cur.execute('INSERT INTO t1 VALUES (%s)', (1,))
cur.execute('INSERT INTO t1 VALUES (%s)', (2,))
conn.commit()
except Exception as e:
conn.rollback()
print(f'Error: {e}')
finally:
conn.close()
| 級別 | 髒讀 | 不可重複讀 | 幻讀 | InnoDB 預設 |
|---|---|---|---|---|
| READ UNCOMMITTED | ✅ | ✅ | ✅ | |
| READ COMMITTED | ❌ | ✅ | ✅ | |
| REPEATABLE READ | ❌ | ❌ | ✅ | ✅ |
| SERIALIZABLE | ❌ | ❌ | ❌ |
InnoDB 預設 REPEATABLE READ,同一交易內重複 SELECT 結果一致(MVCC 快照)。
-- ❌ 絕對更新:讀取→計算→寫入,中間可能被改
UPDATE account SET balance = 100 WHERE id = 1;
-- ✅ 相對更新:單一語句原子操作
UPDATE account SET balance = balance - 50 WHERE id = 1;
LOCK TABLES account WRITE;
-- 多語句操作
UNLOCK TABLES;