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

MySQL 事務完整指南:ACID 特性、控制語句、隔離級別與 Java 實現模板

     編輯:MySQL 綜合教學

MySQL 事務完整指南:ACID 特性、控制語句、隔離級別與 Java 實現模板

事務是資料庫一致性的基石。本文系統講解事務核心概念、ACID 四大特性、SQL 控制語句、隔離級別與鎖關係,並提供 Java JDBC 事務模板代碼,對比一般語句、批處理、事務處理三者差異。

一、 核心概念

定義:一組操作組成的邏輯工作單元,要麼全做,要麼全不做。
經典場景:銀行轉賬 —— 扣款與增款必須同時成功或同時失敗。

二、 事務控制語句

操作SQL 語句說明
開始事務BEGIN / START TRANSACTION標誌事務起點
提交事務COMMIT持久化所有變更
回滾事務ROLLBACK撤銷所有變更
保存點SAVEPOINT name / ROLLBACK TO name部分回滾

三、 ACID 四大特性深度解析

  1. 原子性:事務不可分割,要麼全執行,要麼全不執行。由 Undo Log 保障。
  2. 一致性:事務前後資料庫滿足所有完整性約束(主鍵、外鍵、檢查約束、觸發器等)。
  3. 隔離性:並發事務互不干擾。由鎖 + MVCC 實現,分 4 級隔離級別。
  4. 持久性:提交後永久生效,不因崩潰丟失。由 Redo Log (WAL) 保障。

四、 隔離級別與併發異常

隔離級別髒讀不可重複讀幻讀MySQL 默認
READ UNCOMMITTED✅✅✅
READ COMMITTED❌✅✅
REPEATABLE READ❌❌✅ (間隙鎖緩解)✅ InnoDB 默認
SERIALIZABLE❌❌❌
  • 查看/設置:SELECT @@tx_isolation; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  • InnoDB RR 級別通過 Next-Key Lock(記錄鎖+間隙鎖) 解決大部分幻讀。

五、 三種執行模式對比

1. 一般語句(自動提交)

@Test
public void save1() throws Exception {
    Connection con = ConnFactory.getConn();
    Statement st = con.createStatement();
    st.execute("INSERT INTO stud(id,sname,age) VALUES(1010,'益陽1',25)");
    st.execute("INSERT INTO stud(id,sname,age) VALUES(1010,'益陽2',28)"); // 主鍵衝突拋異常
    st.execute("INSERT INTO stud(id,sname,age) VALUES(1011,'益陽3',25)"); // 不會執行
}

特點:逐條提交,異常中斷後續執行,前面已提交無法回滾。

2. 批處理

@Test
public void save2() throws Exception {
    Connection con = ConnFactory.getConn();
    Statement st = con.createStatement();
    st.addBatch("INSERT INTO stud(id,sname,age) VALUES(1010,'益陽1',25)");
    st.addBatch("INSERT INTO stud(id,sname,age) VALUES(1010,'益陽2',28)"); // 失敗
    st.addBatch("INSERT INTO stud(id,sname,age) VALUES(1011,'益陽3',25)"); // 繼續執行
    st.executeBatch(); // 返回每條影響行數數組
}

特點:一次網絡往返發送多條,合法語句執行,失敗單條不影響其它,**無事務保護**。

3. 事務處理模板(標準 JDBC 模式)

@Test
public void save3() throws Exception {
    Connection con = ConnFactory.getConn();
    try {
        con.setAutoCommit(false); // 關鍵:開啟事務
        Statement st = con.createStatement();
        st.execute("INSERT INTO stud(id,sname,age) VALUES(1010,'益陽1',25)");
        st.execute("INSERT INTO stud(id,sname,age) VALUES(1010,'益陽2',28)"); // 失敗
        st.execute("INSERT INTO stud(id,sname,age) VALUES(1012,'益陽3',25)");
        con.commit(); // 全部成功才提交
    } catch (Exception e) {
        System.out.println("回滾了....");
        con.rollback(); // 任一失敗全量回滾
    } finally {
        con.setAutoCommit(true); // 恢復默認
        con.close();
    }
}

特點:原子性保障,異常自動回滾,資源 finally 釋放。

六、 Java 連接工廠模式(配合事務使用)

// jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/hncu?useUnicode=true&characterEncoding=UTF-8
username=root
password=1234

// ConnFactory.java
public class ConnFactory {
    private static Connection conn;
    static {
        Properties p = new Properties();
        p.load(ConnFactory.class.getClassLoader().getResourceAsStream("jdbc.properties"));
        Class.forName(p.getProperty("driver"));
        conn = DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"), p.getProperty("password"));
    }
    public static Connection getConn() { return conn; }
}

七、 事務使用黃金法則

  1. 業務邊界清晰:一個業務操作 = 一個事務。
  2. 事務盡量短小:減少鎖持有時間,避免長事務阻塞並發。
  3. 異常必捕獲回滾:finally 釋放連接,恢復 autoCommit。
  4. 避免在事務中發起 RPC/HTTP 請求:不可控延遲導致長事務。
  5. 分布式事務:跨庫用 Seata/兩階段提交/本地消息表/事務消息,不在本文範圍。

事務不僅是語法,更是業務一致性的契約。掌握模板,落地規範,讓數據永遠可信。

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