事務是一組 SQL 操作的邏輯單位,遵循「全做或全不做」原則。在多使用者並發環境下,事務確保資料一致性,是並發控制的基本單元。
| 特性 | 說明 |
|---|---|
| 原子性 | 事務內所有操作視為不可分割整體,要麼全成功,要麼全失敗回滾 |
| 一致性 | 事務執行前後,資料庫從一個一致性狀態轉移到另一個一致性狀態 |
| 隔離性 | 並發事務間相互隔離,一個事務的中間狀態對其他事務不可見 |
| 持久性 | 事務提交後,其對資料的修改永久生效,不會因系統故障丟失 |
BEGIN TRANSACTION; -- 開啟事務
COMMIT; -- 提交事務
ROLLBACK; -- 回滾事務
以下程式碼模擬「新增使用者」與「新增地址」兩步操作,若第二步失敗,第一步已提交,造成資料殘缺:
public static void main(String[] args) {
insertUserData(); // 成功插入 1 筆
insertAddressData(); // SQL 語法錯誤拋出例外,但使用者資料已寫入
}
執行結果:
插入了1行用戶數據 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: ... 插入地址失敗,但用戶表已有資料 → 資料不完整
| 方法 | 說明 |
|---|---|
conn.setAutoCommit(false) | 關閉自動提交,手動控制事務邊界 |
conn.commit() | 提交事務,所有操作持久化 |
conn.rollback() | 回滾事務,撤銷所有未提交操作 |
public static void main(String[] args) {
Connection conn = null;
try {
conn = getConnection(); // 取得連線
conn.setAutoCommit(false); // 1. 關閉自動提交
insertUserData(conn); // 2. 執行業務操作
insertAddressData(conn); // 共用同一連線
conn.commit(); // 3. 全部成功 → 提交
System.out.println("事務提交成功");
} catch (SQLException e) {
System.out.println("捕獲 SQL 異常,執行回滾");
e.printStackTrace();
try {
if (conn != null) conn.rollback(); // 4. 任一失敗 → 回滾
System.out.println("事務回滾成功");
} catch (SQLException ex) { ex.printStackTrace(); }
} finally {
try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}
// 修改後的業務方法:接收外部傳入的 Connection,確保同一事務
public static void insertUserData(Connection conn) throws SQLException {
String sql = "INSERT INTO tbl_user(id,name,password,email) VALUES(10,'Tom','123456','tom@qq.com')";
try (Statement st = conn.createStatement()) {
int count = st.executeUpdate(sql);
System.out.println("插入了 " + count + " 行用戶數據");
}
}
public static void insertAddressData(Connection conn) throws SQLException {
String sql = "INSERT INTO tbl_address(id,city,country,user_id) VALUES(1,'shanghai','china',10)";
try (Statement st = conn.createStatement()) {
int count = st.executeUpdate(sql);
System.out.println("插入了 " + count + " 行地址數據");
}
}
插入了 1 行用戶數據 ==========捕獲 SQL 異常========= com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: ... =======事務回滾成功=======
檢查資料庫:tbl_user 與 tbl_address 均無新增資料,確認事務原子性生效。
Connection 物件Statement/ResultSet,但 Connection 需手動控制關閉時機catch 區塊務必呼叫 rollback(),並在 finally 關閉連線conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED) 調整,預設視資料庫而定結語:JDBC 事務控制的關鍵在於「關閉自動提交 → 共用連線執行多步操作 → 成功 commit / 失敗 rollback」。掌握此模式,即可在 Java 應用層面保障資料一致性。