交易是一组原子(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整个批处理。