首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 事務完整教程:ACID 特性、啟動提交回滾、隱式提交陷阱與轉賬實戰

     編輯:MySQL 綜合教學

事務四大特性 (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;

避坑指南

  1. 引擎必須支持事務:InnoDB / BDB,MyISAM 不支持。
  2. 長事務危害大:Undo Log 膨脹、鎖持久、主從延遲、回滾耗時,**業務拆分小事務**。
  3. 異常必須回滾:應用層捕獲異常 → rollback(),否則連接歸池時隱式提交髒數據。
  4. 死鎖自動檢測:InnoDB 會自動回滾代價較小的事務,應用層捕獲 Lock wait timeout exceeded / Deadlock found 重試。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved