目錄
- 1. 什么是事務?
- 2. 事務的ACID特性(重要)
- 3. 事務控制語法
- 4. 隔離級別與并發問題
1. 什么是事務?
事務(Transaction)是由一組SQL語句組成的邏輯單元,這些操作要么全部成功,要么全部失敗。
案例——銀行轉賬:
轉賬成功: 張三給李四轉100元,轉賬之前張三和李四的總額是1000+1000=2000,轉賬之后張三和李四的總額是900+1100=2000,這是正確的結果;
轉賬失敗: 如果在轉賬的過程中張三的余額減了100 之后服務器崩潰了,李四的余額沒有 加100,最終兩個人的余額之和是900+1000=1900;
如果轉賬失敗之后錢莫名其妙的減少了,勢必會帶來很多麻煩
2. 事務的ACID特性(重要)
特性 | 說明 |
---|---|
原子性(Atomicity) | 事務內操作要么全成功,要么全失敗(轉賬失敗則直接退回到初始狀態,成功則落盤保存) |
一致性(Consistency) | 事務前后數據完整性不變 (如轉賬前后總額不變) |
隔離性(Isolation) | 并發事務相互隔離,防止數據干擾 |
持久性(Durability) | 事務提交后數據永久存儲 |
3. 事務控制語法
-- 1. 開啟事務(兩種方式)
START TRANSACTION;
BEGIN;-- 2. 設置保存點
SAVEPOINT savepoint1;-- 3. 提交/回滾
COMMIT; -- 提交
ROLLBACK; -- 回滾
ROLLBACK TO savepoint1; -- 回滾到保存點-- 4. 自動提交設置
SET autocommit = 0; -- 關閉自動提交(默認=1開啟)
注意:
- 已提交的事務不可回滾
- 自動提交模式下,一條SQL就是一個事務
- 顯式開啟事務時(
BEGIN
后),必須手動COMMIT
4. 隔離級別與并發問題
MySQL支持4種隔離級別 (從上到下安全性?? 并發性(性能)??) :
隔離級別 | 臟讀 | 不可重復度 | 幻讀 |
---|---|---|---|
READ UNCOMMITTED (讀未提交) | ? | ? | ? |
READ COMMITTED (讀已提交) | ? | ? | ? |
REPEATABLE READ (可重復度(默認)) | ? | ? | ? |
SERIALIZABLE (串行化) | ? | ? | ? |
MySQL 的 InnoDB 存儲引擎中通過 Next-Key 鎖部分解決幻讀問題,比如有20條數據,如果我正在修改第15條數據,那么第 1 - 15 條數據之間是被鎖住不允許插入內容的,但是 Next-Key 鎖只能鎖住前邊,不能鎖住后邊,所以說是解決部分幻讀問題
- 臟讀:事務 A 讀取了事務 B 未提交的數據
- 例:B 修改數據中途崩潰,A 讀到中間狀態的數據,那么 A 讀到的就是沒有提交的垃圾數據
- 不可重復讀:同事務內兩次讀取結果不同(數據值變化)
- 幻讀 :相同的查詢條件兩次返回數據的行數不同
- 例:A 查詢余額 >500 的賬戶,期間 B 新增滿足條件的賬戶
生產建議:
MySQL 默認REPEATABLE READ
在多數場景下平衡性能與安全
金融系統可考慮SERIALIZABLE
,但需測試性能影響
謹慎使用READ UNCOMMITTED
(僅適用于可容忍臟讀的場景)