JDBC手動事務提交回滾的常見寫法一直是rollback寫在commit的catch以後:java
try{ conn.setAutoCommit(false); ps.executeUpdate(); ps.executeUpdate(); conn.commit(); }catch(Exception e){ conn.rollback(); }
可是,這種回滾是沒有意義的:mysql
一旦commit前出錯, 就不提交了, 回滾無用sql
一旦commit了, 說明沒錯, 不用回滾spa
找到一篇和我觀點相同的文章:.net
<JDBC 事務的回滾 提交>
code
我覺得無需回滾,即便真要回滾,須要將commit寫在主要業務的try...catch以後,一旦主要業務中途出錯,回滾.blog
表:JDBC事務3種寫法回滾比較事務
import java.sql.*; public class TestJDBC { public static final String URL = "jdbc:mysql://127.0.0.1/test"; public static final String USER_NAME = "root"; public static final String USER_PWD = "root"; private static Connection conn = null; private static PreparedStatement ps; private static void connOpen() throws SQLException { conn = DriverManager.getConnection(URL, USER_NAME, USER_PWD); } private static void connClose() throws SQLException { if (ps != null) { ps.close(); ps = null; } if (conn != null) { conn.close(); conn = null; } } private static void testRollBack() throws SQLException { connOpen(); try { conn.setAutoCommit(false); String strSQL = "INSERT INTO customer(uname,pwd) VALUES(?,'1')"; ps = conn.prepareStatement(strSQL); // 插入一條數據 ps.setString(1, "悟空"); ps.executeUpdate(); // 出異常 if (true) { throw new SQLException(); } // 再插入一條數據 ps.setString(1, "八戒"); ps.executeUpdate(); // conn.commit(); } catch (Exception e) { System.out.println("異常!"); try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } try { conn.commit(); } catch (SQLException e) { e.printStackTrace(); } connClose(); } private static void selectAll() throws SQLException { connOpen(); ps = conn.prepareStatement("select * from customer"); ResultSet rs = ps.executeQuery(); while (rs.next()) { System.out.print(rs.getString(2) + " : "); System.out.println(rs.getString(1)); } connClose(); } public static void main(String[] args) throws SQLException { testRollBack(); selectAll(); } }