本例演示完整的 JDBC 事務處理流程:關閉自動提交、批量執行 DML、條件查詢、異常回滾、資源釋放。使用 Oracle 數據庫為例,代碼結構清晰分層。
public class JDBCConnCommit {
private static String url, username, password;
// 1. 獲取連接
public Connection conn() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
return DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException | SQLException | Exception e) { ... return null; }
}
// 2. 查詢
public void query(Connection con, String sql) throws SQLException, Exception {
if (con == null) throw new Exception("database connection can't use!");
if (sql == null) throw new Exception("check your parameter: 'sql'! don't input null!");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
ResultSetMetaData rmeta = rs.getMetaData();
int numColumns = rmeta.getColumnCount();
while (rs.next()) {
for (int i = 0; i < numColumns; i++) System.out.print(rs.getString(i+1) + " ");
System.out.println();
}
rs.close(); stmt.close();
}
// 3. 執行 DML (insert/update/delete)
public void execute(Connection con, String sql) throws SQLException {
if (con == null) return;
Statement stmt = con.createStatement();
int i = stmt.executeUpdate(sql);
System.out.println("update row: " + i);
stmt.close();
}
// 4. 事務演示
public void demo() {
Connection conn = conn();
try {
conn.setAutoCommit(false); // 關鍵:開啟事務
String sql = "";
for (int i = 0; i < 4; i++) {
sql = "insert into TBL_USER(id,name,password) values(seq_user.nextval,'tom','haorenpingan')";
execute(conn, sql);
}
sql = "select * from TBL_USER where name='tom' order by id";
query(conn, sql);
sql = "delete from TBL_USER where name='tom'";
execute(conn, sql);
conn.commit(); // 全部成功提交
} catch (SQLException se) {
try { conn.rollback(); } catch (Exception e) {} // 異常回滾
System.out.println(se);
} catch (Exception e) { System.out.println(e); }
finally {
try { conn.close(); } catch (SQLException e) {}
}
}
public static void main(String[] arg) {
if (arg.length != 3) { System.out.println("use: java JDBCConnCommit url username password"); return; }
JDBCConnCommit oc = new JDBCConnCommit();
oc.url = arg[0]; oc.username = arg[1]; oc.password = arg[2];
oc.demo();
}
}
| 步驟 | 代碼 | 說明 |
|---|---|---|
| 關閉自動提交 | conn.setAutoCommit(false) | 默認 true,每條 SQL 獨立提交;改為 false 後需手動 commit |
| 執行業務 SQL | executeUpdate() | 多條 DML 組成邏輯事務單元 |
| 提交事務 | conn.commit() | 所有操作成功才調用,持久化變更 |
| 異常回滾 | conn.rollback() | catch 塊中調用,撤銷事務內所有變更 |
| 資源釋放 | finally { conn.close() } | 確保連接歸還池,防洩漏 |
addBatch() + executeBatch() 減少網絡往返Savepoint sp = conn.setSavepoint(); conn.rollback(sp); 部分回滾@Transactional 替代手動管理try (Connection conn = dataSource.getConnection()) {
conn.setAutoCommit(false);
try (PreparedStatement ps = conn.prepareStatement(sql)) {
// 設置參數 ps.setString(1, val)...
ps.executeUpdate();
}
conn.commit();
} catch (SQLException e) {
// 連接自動關閉,事務自動回滾(若未提交)
throw new RuntimeException(e);
}
try-with-resources (Java 7+) 自動關閉資源,簡化 finally 代碼。