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

MySQL 事務完整指南:ACID 特性、隔離級別、JDBC 控制與最佳實踐

     編輯:MySQL 綜合教學

MySQL 事務完整指南:ACID 特性、隔離級別、JDBC 控制與最佳實踐

事務是數據庫區別於文件系統的核心特性,本文系統講解 MySQL 事務的原理、特性、隔離級別、程序化控制與生產環境注意事項。

一、事務基本概念

事務:邏輯上的一組操作,組成單元要麼全成功,要麼全失敗。

  • MySQL 中 InnoDB 引擎支援事務,MyISAM 不支援
  • 默認自動提交模式:autocommit=ON,每條語句隱式事務
  • 手動控制:BEGIN / START TRANSACTION 開啟,COMMIT 提交,ROLLBACK 回滾

二、ACID 四大特性深度解析

特性英文核心含義MySQL 實現機制
原子性Atomicity事務為不可分割單元,全做或全不做Undo Log 記錄舊值,回滾時反向操作
一致性Consistency事務前後數據庫從一個一致性狀態變換到另一個約束(PK/FK/UK/CHECK)+ 原子性/隔離性/持久性共同保證
隔離性Isolation並發事務互不干擾,多種隔離級別權衡性能與一致性MVCC(多版本並發控制)+ 鎖機制
持久性Durability提交後改變永久生效,故障也不丟失Redo Log(WAL機制)+ sync_binlog=1 + innodb_flush_log_at_trx_commit=1

三、四大隔離級別與並發異常

隔離級別髒讀不可重複讀幻讀性能MySQL 默認
READ UNCOMMITTED✅ 可能✅ 可能✅ 可能最高否
READ COMMITTED❌ 避免✅ 可能✅ 可能高Oracle 默認
REPEATABLE READ❌ 避免❌ 避免⚠️ 可能(間隙鎖緩解)中是
SERIALIZABLE❌ 避免❌ 避免❌ 避免最低否

異常定義:

  • 髒讀:讀到未提交事務的數據
  • 不可重複讀:同一事務多次讀取同一行,結果不同(被其他事務 UPDATE)
  • 幻讀:同一事務多次範圍查詢,行數不同(被其他事務 INSERT/DELETE)

四、MySQL 隔離級別操作

-- 查看當前會話隔離級別
SELECT @@TX_ISOLATION;
-- 或
SELECT @@TRANSACTION_ISOLATION;

-- 設置當前會話隔離級別(需在事務開啟前)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 設置全局默認(需重啟或新連接生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

五、JDBC 程序化事務控制

Connection conn = null;
PreparedStatement ps = null;
try {
    conn = dataSource.getConnection();
    conn.setAutoCommit(false);  // 關鍵:關閉自動提交,等同於 BEGIN

    // 業務邏輯 1
    ps = conn.prepareStatement("UPDATE account SET money = money - 100 WHERE id = 1");
    ps.executeUpdate();

    // 模擬業務異常
    // int i = 1 / 0;  // 取消註釋測試回滾

    // 業務邏輯 2
    ps = conn.prepareStatement("UPDATE account SET money = money + 100 WHERE id = 2");
    ps.executeUpdate();

    conn.commit();  // 顯式提交
} catch (Exception e) {
    if (conn != null) {
        try { conn.rollback(); } catch (SQLException ex) { log.error("Rollback failed", ex); }
    }
    throw new RuntimeException("Transaction failed", e);
} finally {
    // 資源關閉建議使用 try-with-resources (JDK 7+)
    if (ps != null) try { ps.close(); } catch (SQLException e) { /* ignore */ }
    if (conn != null) try { conn.close(); } catch (SQLException e) { /* ignore */ }
}

六、Spring @Transactional 關鍵屬性

屬性說明建議值
propagation傳播行為REQUIRED(默認)
isolation隔離級別READ_COMMITTED(高併發) / REPEATABLE READ(默認)
timeout超時時間(秒)30-60,防止長事務阻塞
readOnly只讀優化查詢方法設 true
rollbackFor回滾異常類Exception.class(默認僅 RuntimeException)

七、生產環境最佳實踐

  1. 事務粒度最小化:僅包含必要寫操作,查詢移至事務外
  2. 避免長事務:超過 1 秒視為長事務,拆分批次提交
  3. 合理選擇隔離級別:高併發讀多寫少場景推薦 READ COMMITTED + 悲觀鎖/樂觀鎖
  4. 死鎖處理:捕獲 Lock wait timeout exceeded / Deadlock found,指數退避重試
  5. 監控指標:Innodb_row_lock_waits、Innodb_row_lock_time_avg、Trx_rseg_history_len(Undo 積壓)
  6. 分布式事務:Seata AT 模式 / TCC / SAGA,根據業務一致性要求選型

八、常見誤區

  • ❌ 以為 SELECT 不加鎖:RR 級別下普通 SELECT 是快照讀,但 SELECT ... LOCK IN SHARE MODE / FOR UPDATE 會加鎖
  • ❌ 認為自動提交無事務開銷:每條語句仍有隱式事務啟動/提交成本
  • ❌ 忽略 autocommit 連接池默認值:Druid/HikariCP 默認 autoCommit=true,框架層接管

深入理解事務機制,是編寫高可靠、高併發數據訪問層代碼的基石。

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