交易是一組原子(Atomic)操作(一組SQL執行)的工作單元,這個工作單元中的所有原子操作在進行期間,與其它交易隔離,免於數據來源的交相更新而
發生混亂,交易中的所有原子操作,要嘛全部執行成功,要嘛全部失敗(即使只有一個失敗,所有的原子操作也要全部撤消)。
舉個簡單的例子,一個客戶從A銀行轉帳至B銀行,要作的動作為從A銀行的帳戶扣款、在B銀行的帳戶加上轉帳的金額,兩個動作必須成功,如果有一個動作失敗,則此次轉帳失敗。
在JDBC中,可以操作Connection的setAutoCommit()方法,給定它false引數,在下達一連串的SQL語句後,自行呼叫Connection的commit()來送出變更,如果中間發生錯誤,則呼叫rollback()來撤消所有的執行,例如:
package onlyfun.caterpillar; import java.sql.*; public class TransactionDemo { private static String driver = "com.mysql.jdbc.Driver"; private static String url = "jdbc:mysql://localhost:3306/demo"; private static String user = "root"; private static String password = "123456"; private static void loadDriver() { try { Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { loadDriver();
Connection conn = null; Statement stmt = null;
try { conn = DriverManager.getConnection( url, user, password); conn.setAutoCommit(false);
stmt = conn.createStatement();
stmt.execute("...."); // SQL stmt.execute("...."); stmt.execute("...."); conn.commit(); } catch(SQLException e) { try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); } finally { if(stmt != null) { try { stmt.close(); } catch(SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } } }
如果您在交易管理時,僅想要rollback回某個SQL執行點,則您可以設定save point,例如:
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate("....");
stmt.executeUpdate("....");
Savepoint savepoint = conn.setSavepoint(); // 設定save point
stmt.executeUpdate("....");
// 如果因故rollback
conn.rollback(savepoint);
. . .
conn.commit();
// 記得釋放save point
stmt.releaseSavepoint(savepoint);
在 Statement 批次處理 中介紹過批次執行SQL,批次處理前設定auto commit為 false,如果中間有個SQL執行錯誤,則應該rollback整個批次處理。
|