MySQL 默認自動提交:
SHOW VARIABLES LIKE 'AUTOCOMMIT'; -- ON SET AUTOCOMMIT = 0; -- 關閉,開啟顯式事務
InnoDB 事務開始獲取隱式鎖,提交/回滾釋放。支持顯式鎖:
SELECT ... FOR UPDATE; -- 排他鎖 SELECT ... LOCK IN SHARE MODE; -- 共享鎖
建議:除禁用 AUTOCOMMIT 配合 LOCK TABLES 外,避免顯式 LOCK TABLES。
• 非 MySQL 獨有,Oracle/PostgreSQL 也用。
• 不用簡單行鎖,而是「行級別鎖」。
• 核心:保存數據在某時間點的快照,事務無論運行多久,看到的數據視圖一致。不同時刻啟動的事務看到的同表數據可能不同。
每行隱藏兩列:
• trx_id:創建版本號(系統版本號)
• roll_pointer:刪除版本號(指向 undo log)
系統版本號隨事務啟動遞增,事務版本號 = 啟動時系統版本號。CRUD 操作邏輯:
僅返回滿足雙條件的行:
1. 行創建版本 ≤ 事務版本(數據在事務開始前已存在或由事務自身創建/修改)
2. 行刪除版本未定義 或 > 事務版本(事務開始前未被刪除)
保存當前系統版本號為行版本號。
保存當前系統版本號為行刪除標識。
插入新行(版本號 = 當前系統版本號),舊行標記刪除版本號 = 當前系統版本號。
優: 大多操作無需加鎖,讀寫不阻塞,性能極佳。
缺: 每行額外存儲版本信息,需更多行檢查與維護開銷。
僅在 REPEATABLE READ 和 READ COMMITTED 下工作,其他級別不兼容。
嚴格說 InnoDB 算不上理想 MVCC,因為未實現核心的多版本共存,undo log 只是串行化記錄。理想 MVCC 難以處理多行修改的原子性回滾(需二階段提交/鎖定),InnoDB 借用 MVCC 名稱實現「讀不阻塞」,實際依賴鎖機制保證寫一致性。