ITEEDU

Java Gossip: 交易(Transaction)

交易是一组原子(Atomic)操作(一组SQL执行)的工作单元,这个工作单元中的所有原子操作在进行期间,与其它交易隔离,免于数据来源的交相更新而 发生混乱,交易中的所有原子操作,要嘛全部执行成功,要嘛全部失败(即使只有一个失败,所有的原子操作也要全部撤消)。

举个简单的例子,一个客户从A银行转帐至B银行,要作的动作为从A银行的账户扣款、在B银行的账户加上转帐的金额,两个动作必须成功,如果有一个动作失败,则此次转帐失败。

在JDBC中,可以操作Connection的setAutoCommit()方法,给定它false自变量,在下达一连串的SQL语句后,自行呼叫Connection的commit()来送出变更,如果中间发生错误,则呼叫rollback()来撤消所有的执行,例如:

TransactionDemo.java
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整个批处理。