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