Mysql事務(wù)與存儲(chǔ)引擎全解(概念、原理、代碼示例)
在 MySQL 中,事務(wù)是保證數(shù)據(jù)一致性的核心機(jī)制,存儲(chǔ)引擎則是 MySQL 處理數(shù)據(jù)的底層引擎,兩者是數(shù)據(jù)庫(kù)開(kāi)發(fā)、面試的高頻考點(diǎn)。本文圍繞圖片中的知識(shí)點(diǎn),從概念、原理、代碼示例三個(gè)維度,帶你徹底掌握 MySQL 事務(wù)與存儲(chǔ)引擎。
一、核心知識(shí)點(diǎn)總覽
| 大類(lèi) | 細(xì)分知識(shí)點(diǎn) | 核心作用 |
|---|---|---|
| 事務(wù)基礎(chǔ) | 1. 事務(wù)引例 | 理解事務(wù)的實(shí)際應(yīng)用場(chǎng)景 |
| 2. 相關(guān)概念 | 事務(wù)的定義、執(zhí)行流程 | |
| 3. 存儲(chǔ)引擎 | 事務(wù)與存儲(chǔ)引擎的依賴(lài)關(guān)系 | |
| 4. ACID 屬性 | 事務(wù)的四大核心特性(面試必背) | |
| 5. 銀行轉(zhuǎn)賬演示 | 事務(wù)的實(shí)際代碼實(shí)戰(zhàn) | |
| 事務(wù)并發(fā)與隔離 | 6. 事務(wù)的并發(fā)問(wèn)題 | 臟讀、不可重復(fù)讀、幻讀 |
| 7. 事務(wù)隔離性 | 四大隔離級(jí)別 | |
| 8. 隔離級(jí)別總結(jié) | 隔離級(jí)別對(duì)比、MySQL 默認(rèn)級(jí)別 | |
| 9. 隔離級(jí)別演示 | 不同隔離級(jí)別下的問(wèn)題演示 | |
| 存儲(chǔ)引擎 | 10. 存儲(chǔ)引擎 | InnoDB、MyISAM 等核心引擎對(duì)比 |
二、一、事務(wù)基礎(chǔ):從概念到 ACID
1. 事務(wù)是什么?
事務(wù)(Transaction)是一組不可分割的 SQL 操作單元,要么全部執(zhí)行成功,要么全部執(zhí)行失敗,保證數(shù)據(jù)的一致性。
經(jīng)典場(chǎng)景:銀行轉(zhuǎn)賬(A 給 B 轉(zhuǎn)錢(qián),A 扣錢(qián)和 B 加錢(qián)必須同時(shí)成功 / 失?。?/p>
2. 事務(wù)的執(zhí)行流程
-- 開(kāi)啟事務(wù) START TRANSACTION; -- 或 BEGIN; -- 執(zhí)行SQL操作 UPDATE account SET money = money - 100 WHERE name = 'A'; UPDATE account SET money = money + 100 WHERE name = 'B'; -- 提交事務(wù)(全部生效) COMMIT; -- 回滾事務(wù)(全部撤銷(xiāo),出現(xiàn)異常時(shí)執(zhí)行) ROLLBACK;
3. 事務(wù)的 ACID 屬性
事務(wù)必須滿(mǎn)足四大核心特性,簡(jiǎn)稱(chēng) ACID:
| 屬性 | 全稱(chēng) | 核心含義 |
|---|---|---|
| A | Atomicity(原子性) | 事務(wù)是不可分割的最小單元,要么全成功,要么全失敗 |
| C | Consistency(一致性) | 事務(wù)執(zhí)行前后,數(shù)據(jù)的完整性約束不變(如轉(zhuǎn)賬前后總金額不變) |
| I | Isolation(隔離性) | 多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),互不干擾,互不影響 |
| D | Durability(持久性) | 事務(wù)提交后,數(shù)據(jù)永久寫(xiě)入數(shù)據(jù)庫(kù),不會(huì)丟失 |
4. 銀行轉(zhuǎn)賬的事務(wù)演示(代碼實(shí)戰(zhàn))
準(zhǔn)備工作:創(chuàng)建賬戶(hù)表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
money DECIMAL(10,2) NOT NULL
) ENGINE=InnoDB; -- 必須用InnoDB(支持事務(wù))
INSERT INTO account (name, money) VALUES
('A', 1000.00),
('B', 500.00);事務(wù)轉(zhuǎn)賬代碼
-- 開(kāi)啟事務(wù) START TRANSACTION; -- A扣100 UPDATE account SET money = money - 100 WHERE name = 'A'; -- 模擬異常(手動(dòng)報(bào)錯(cuò),測(cè)試回滾) -- SELECT 1/0; -- B加100 UPDATE account SET money = money + 100 WHERE name = 'B'; -- 提交事務(wù) COMMIT; -- 若出現(xiàn)異常,執(zhí)行回滾 -- ROLLBACK; -- 查看結(jié)果 SELECT * FROM account;
結(jié)果說(shuō)明
- 正常執(zhí)行:A 余額 900,B 余額 600,總金額 1500 不變(一致性)
- 異?;貪L:兩條 UPDATE 全部撤銷(xiāo),A、B 余額不變(原子性)
三、二、事務(wù)并發(fā)問(wèn)題與隔離級(jí)別
1. 事務(wù)的三大并發(fā)問(wèn)題
多個(gè)事務(wù)同時(shí)操作同一數(shù)據(jù)時(shí),會(huì)出現(xiàn)以下問(wèn)題:
| 問(wèn)題 | 核心含義 | 危害 |
|---|---|---|
| 臟讀 | 一個(gè)事務(wù)讀取了另一個(gè)事務(wù)未提交的數(shù)據(jù),后續(xù)該事務(wù)回滾,讀取的數(shù)據(jù)無(wú)效 | 讀取到錯(cuò)誤數(shù)據(jù) |
| 不可重復(fù)讀 | 一個(gè)事務(wù)內(nèi)兩次讀取同一數(shù)據(jù),中間被另一個(gè)事務(wù)修改,兩次讀取結(jié)果不一致 | 同一事務(wù)內(nèi)數(shù)據(jù)不一致 |
| 幻讀 | 一個(gè)事務(wù)內(nèi)兩次查詢(xún)同一范圍數(shù)據(jù),中間被另一個(gè)事務(wù)插入 / 刪除數(shù)據(jù),兩次查詢(xún)結(jié)果行數(shù)不一致 | 數(shù)據(jù)行數(shù)不一致,像 “幻覺(jué)” |
2. 四大事務(wù)隔離級(jí)別(解決并發(fā)問(wèn)題)
MySQL 通過(guò)隔離級(jí)別控制事務(wù)的隔離程度,級(jí)別越高,并發(fā)問(wèn)題越少,但性能越低:
| 隔離級(jí)別 | 英文 | 解決的問(wèn)題 | 臟讀 | 不可重復(fù)讀 | 幻讀 | MySQL 默認(rèn) |
|---|---|---|---|---|---|---|
| 讀未提交 | READ UNCOMMITTED | 最低級(jí)別,無(wú)隔離 | ? 存在 | ? 存在 | ? 存在 | 否 |
| 讀已提交 | READ COMMITTED | 僅讀取已提交數(shù)據(jù) | ? 避免 | ? 存在 | ? 存在 | 否(Oracle 默認(rèn)) |
| 可重復(fù)讀 | REPEATABLE READ | 同一事務(wù)內(nèi)數(shù)據(jù)重復(fù)讀取一致 | ? 避免 | ? 避免 | ? 存在(MySQL 特殊優(yōu)化) | ? 是(MySQL 默認(rèn)) |
| 串行化 | SERIALIZABLE | 事務(wù)串行執(zhí)行,完全隔離 | ? 避免 | ? 避免 | ? 避免 | 否 |
MySQL 特殊說(shuō)明:InnoDB 在
REPEATABLE READ級(jí)別下,通過(guò) MVCC(多版本并發(fā)控制) 避免了幻讀,是 MySQL 的默認(rèn)級(jí)別,兼顧性能與一致性。
3. 隔離級(jí)別演示(核心場(chǎng)景)
(1)讀未提交(READ UNCOMMITTED):臟讀演示
-- 事務(wù)1:開(kāi)啟事務(wù),修改數(shù)據(jù)但不提交 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; START TRANSACTION; UPDATE account SET money = 900 WHERE name = 'A'; -- 事務(wù)2:讀取A的余額(讀到了未提交的數(shù)據(jù),臟讀) START TRANSACTION; SELECT money FROM account WHERE name = 'A'; -- 結(jié)果:900 -- 事務(wù)1:回滾 ROLLBACK; -- 事務(wù)2:再次讀取,結(jié)果變回1000(臟讀導(dǎo)致數(shù)據(jù)不一致) SELECT money FROM account WHERE name = 'A'; -- 結(jié)果:1000
(2)讀已提交(READ COMMITTED):不可重復(fù)讀演示
-- 事務(wù)1:開(kāi)啟事務(wù) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION; -- 第一次讀取A的余額 SELECT money FROM account WHERE name = 'A'; -- 結(jié)果:1000 -- 事務(wù)2:修改并提交 START TRANSACTION; UPDATE account SET money = 900 WHERE name = 'A'; COMMIT; -- 事務(wù)1:第二次讀取,結(jié)果變?yōu)?00(不可重復(fù)讀) SELECT money FROM account WHERE name = 'A'; -- 結(jié)果:900
(3)可重復(fù)讀(REPEATABLE READ):避免不可重復(fù)讀,幻讀演示
-- 事務(wù)1:開(kāi)啟事務(wù)(默認(rèn)級(jí)別)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
-- 第一次查詢(xún)余額>800的記錄
SELECT * FROM account WHERE money > 800; -- 結(jié)果:A(1000)
-- 事務(wù)2:插入新記錄并提交
START TRANSACTION;
INSERT INTO account (name, money) VALUES ('C', 900.00);
COMMIT;
-- 事務(wù)1:第二次查詢(xún),結(jié)果仍為A(1000)(MySQL MVCC避免幻讀)
SELECT * FROM account WHERE money > 800;
-- 若手動(dòng)關(guān)閉MVCC,會(huì)出現(xiàn)幻讀(第二次查詢(xún)出現(xiàn)C的記錄)(4)串行化(SERIALIZABLE):完全避免所有問(wèn)題
-- 事務(wù)1:開(kāi)啟串行化隔離級(jí)別 SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION; SELECT * FROM account; -- 事務(wù)2:嘗試修改數(shù)據(jù),會(huì)被阻塞,直到事務(wù)1提交/回滾 START TRANSACTION; UPDATE account SET money = 900 WHERE name = 'A'; -- 阻塞
四、三、存儲(chǔ)引擎詳解
1. 什么是存儲(chǔ)引擎?
存儲(chǔ)引擎是 MySQL 處理數(shù)據(jù)的底層組件,負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)、提取、事務(wù)管理等,MySQL 支持多種存儲(chǔ)引擎,不同引擎特性不同。
2. 核心存儲(chǔ)引擎對(duì)比(面試必背)
| 存儲(chǔ)引擎 | 事務(wù)支持 | 外鍵支持 | 鎖粒度 | 適用場(chǎng)景 |
|---|---|---|---|---|
| InnoDB | ? 支持 | ? 支持 | 行級(jí)鎖 | 事務(wù)型業(yè)務(wù)(如銀行、電商),MySQL 5.5+ 默認(rèn)引擎 |
| MyISAM | ? 不支持 | ? 不支持 | 表級(jí)鎖 | 讀多寫(xiě)少的場(chǎng)景(如日志、報(bào)表),不支持事務(wù) |
| Memory | ? 不支持 | ? 不支持 | 表級(jí)鎖 | 臨時(shí)表、緩存,數(shù)據(jù)存儲(chǔ)在內(nèi)存中,重啟丟失 |
| Archive | ? 不支持 | ? 不支持 | 行級(jí)鎖 | 歸檔存儲(chǔ),高壓縮比,僅支持插入 / 查詢(xún) |
3. 存儲(chǔ)引擎相關(guān)操作
-- 查看MySQL支持的存儲(chǔ)引擎
SHOW ENGINES;
-- 查看表的存儲(chǔ)引擎
SHOW TABLE STATUS LIKE 'account';
-- 修改表的存儲(chǔ)引擎
ALTER TABLE account ENGINE = MyISAM;
-- 創(chuàng)建表時(shí)指定存儲(chǔ)引擎
CREATE TABLE test (
id INT PRIMARY KEY
) ENGINE=InnoDB;4. InnoDB 核心特性
- 支持事務(wù)、外鍵、行級(jí)鎖、MVCC
- 支持崩潰恢復(fù),保證數(shù)據(jù)安全
- 是 MySQL 生產(chǎn)環(huán)境的首選引擎
五、核心總結(jié)(面試速記)
1. 事務(wù)核心
- ACID:原子性、一致性、隔離性、持久性
- 并發(fā)問(wèn)題:臟讀、不可重復(fù)讀、幻讀
- 隔離級(jí)別:讀未提交 → 讀已提交 → 可重復(fù)讀(MySQL 默認(rèn)) → 串行化
- 事務(wù)語(yǔ)法:
START TRANSACTION/BEGIN→COMMIT/ROLLBACK
2. 存儲(chǔ)引擎核心
- InnoDB:默認(rèn)引擎,支持事務(wù)、外鍵、行鎖,適用于事務(wù)型業(yè)務(wù)
- MyISAM:不支持事務(wù),讀性能高,適用于讀多寫(xiě)少場(chǎng)景
- 事務(wù)僅 InnoDB 支持,MyISAM 無(wú)事務(wù)能力
六、避坑指南
- 事務(wù)依賴(lài)存儲(chǔ)引擎:只有 InnoDB 支持事務(wù),MyISAM 執(zhí)行事務(wù)語(yǔ)句不會(huì)報(bào)錯(cuò),但不會(huì)生效
- 隔離級(jí)別設(shè)置:
SET SESSION僅對(duì)當(dāng)前會(huì)話(huà)生效,全局設(shè)置需修改my.cnf - 幻讀在 MySQL 中的特殊處理:InnoDB 默認(rèn)級(jí)別
REPEATABLE READ下,通過(guò) MVCC 避免了幻讀,與標(biāo)準(zhǔn) SQL 不同 - 事務(wù)回滾時(shí)機(jī):必須在
COMMIT之前執(zhí)行,提交后無(wú)法回滾
到此這篇關(guān)于Mysql事務(wù)與存儲(chǔ)引擎全解(概念、原理、代碼示例)的文章就介紹到這了,更多相關(guān)mysql事務(wù)與存儲(chǔ)引擎內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
windows下mysql 8.0.12安裝步驟及基本使用教程
這篇文章主要為大家詳細(xì)介紹了windows下mysql 8.0.12安裝步驟及基本使用教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
MySQL 8.0 新特性之檢查約束的實(shí)現(xiàn)
這篇文章主要介紹了MySQL 8.0 新特性之檢查約束的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
解決Windows安裝mysql時(shí)提示MSVCR120.DLL動(dòng)態(tài)庫(kù)缺失問(wèn)題
在Windows Server 2012系統(tǒng)上安裝MySQL 5.7時(shí)遇到“由于找不到MSVCR120.dll,無(wú)法繼續(xù)執(zhí)行代碼”的錯(cuò)誤,原因是系統(tǒng)缺少部分配置文件,解決方法是下載并安裝vcredist文件2025-02-02
MySQL報(bào)錯(cuò)1067 :Invalid default value for&n
在使用MySQL5.7時(shí),還原數(shù)據(jù)庫(kù)的時(shí)候報(bào)錯(cuò),下面就來(lái)介紹一下MySQL報(bào)錯(cuò)1067 :Invalid default value for ‘字段名’,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05
MySQL復(fù)制出錯(cuò) Last_SQL_Errno:1146的解決方法
這篇文章主要介紹了MySQL復(fù)制出錯(cuò) Last_SQL_Errno:1146的解決方法,需要的朋友可以參考下2016-07-07
在 Windows 10 上安裝 解壓縮版 MySql(推薦)
這篇文章主要介紹了在 Windows 10 上安裝 解壓縮版 MySql(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
mysql下優(yōu)化表和修復(fù)表命令使用說(shuō)明(REPAIR TABLE和OPTIMIZE TABLE)
隨著mysql的長(zhǎng)期使用,肯定會(huì)出現(xiàn)一些問(wèn)題,一般情況下mysql表無(wú)法訪問(wèn),就可以修復(fù)表了,優(yōu)化時(shí)減少磁盤(pán)占用空間。方便備份。2011-01-01

