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

MySQL 事務完整指南:ACID 特性、啟動提交回滾、保存點與轉賬實戰

     編輯:MySQL 綜合教學

MySQL 事務完整指南:ACID 特性、啟動提交回滾、保存點與轉賬實戰

事務是資料庫區別於文件系統的核心特性,保證數據在並發、故障場景下的一致性。本文以支付寶轉賬為例,圖解 MySQL 事務的四大特性 (ACID)、顯式事務控制語句、保存點機制及最佳實踐。

什麼是事務?—— 支付寶轉賬場景

張三轉 1000 元給李四,涉及兩條 SQL:

UPDATE account SET balance = balance - 1000 WHERE id = 1; -- 張三扣款
UPDATE account SET balance = balance + 1000 WHERE id = 2; -- 李四入賬

若第一條成功、第二條執行前發生故障 (網線被挖斷、進程崩潰),張三錢少了、李四沒收到,**數據不一致**。事務機制確保:**要麼全成功,要麼全失敗,不存在中間態**。

事務四大特性 (ACID)

特性英文通俗解釋
原子性Atomicity事務內所有操作是不可分割的原子單元,全做或全不做
一致性Consistency事務執行前後,數據庫從一個一致性狀態變換到另一個一致性狀態 (如轉賬前後總金額不變)
隔離性Isolation並發事務之間互不干擾,MySQL 通過鎖 + MVCC 實現 (READ COMMITTED / REPEATABLE READ 等級別)
持久性Durability事務提交後,修改永久保存,即使數據庫崩潰重啟也能通過 Redo Log 恢復

MySQL 顯式事務控制語句

  • 默認情況:每條 SQL 自動提交 (autocommit=ON)。
  • 開啟事務:START TRANSACTION; 或 BEGIN; (標記事務起點)。
  • 提交事務:COMMIT; (持久化所有修改)。
  • 回滾事務:ROLLBACK; (撤銷事務起點以來所有修改)。

轉賬實戰演示

場景 A:放棄事務 (轉賬失敗,數據回滾)

START TRANSACTION;
UPDATE account SET balance = balance - 1000 WHERE id = 1;
UPDATE account SET balance = balance + 1000 WHERE id = 2;
ROLLBACK; -- 故意回滾,模擬業務邏輯判斷失敗

結果:張三、李四餘額均不變。

場景 B:提交事務 (轉賬成功)

START TRANSACTION;
UPDATE account SET balance = balance - 1000 WHERE id = 1;
UPDATE account SET balance = balance + 1000 WHERE id = 2;
COMMIT; -- 確認無誤,持久化

結果:張三 -1000,李四 +1000,總額守恆。

場景 C:保存點 - 部分回滾

START TRANSACTION;
UPDATE account SET balance = balance - 1000 WHERE id = 1;
SAVEPOINT sp1; -- 設置保存點
UPDATE account SET balance = balance + 1000 WHERE id = 2; -- 假設這條報錯或業務判斷需撤銷
ROLLBACK TO SAVEPOINT sp1; -- 回滾到 sp1,僅撤銷第二條 UPDATE
COMMIT; -- 提交第一條 UPDATE (張三扣款生效,李四未入賬 - 業務邏輯通常不這樣做,演示語法)

保存點用途:嵌套業務邏輯中,內層失敗需回滾到外層某個檢查點,而非整個事務回滾。

Java/JDBC 中事務控制模式

Connection con = dataSource.getConnection();
try {
    con.setAutoCommit(false); // 關鍵:關閉自動提交
    // 業務 SQL 1
    // 業務 SQL 2
    con.commit(); // 全部成功提交
} catch (SQLException e) {
    try { con.rollback(); } catch (SQLException ex) { log.error("回滾失敗", ex); }
    throw new RuntimeException("事務執行失敗", e);
} finally {
    try { con.setAutoCommit(true); } catch (SQLException e) { log.warn("恢復自動提交失敗", e); }
    close(con);
}

最佳實踐原則

  1. 事務盡可能短:只包含必要的寫操作,避免長事務佔用鎖、阻塞並發、增加死鎖概率。
  2. 業務邊界 = 事務邊界:Service 層控制事務,DAO 不自行提交/回滾。
  3. 異常即回滾:RuntimeException 觸發回滾;檢查異常需手動判斷。
  4. 只讀事務優化:@Transactional(readOnly=true) 可提示優化器、避免不必要的鎖。
  5. 隔離級別選擇:默認 REPEATABLE READ (防幻讀);高並發讀多寫少可考慮 READ COMMITTED + Binlog ROW 格式。

--- 完 ---

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved