第 33 节 批处理与事务处理

在之前所使用的全部的数据库操作严格来讲是属于JDBC1.0中就规定的操作模式,而最新的JDBC是4.0版本,但是没人去使用,从JDBC2.0开始增加了一些神奇功能:可滚动的结果集、可以利用结果集执行增加、更新、删除操作、批处理操作。

所谓的批处理指的是一次性向数据库中发出多条操作命令,一起执行。如果要想操作批处理主要还是在StatmentPreparedStatment接口上定义的。

  • Statement接口定义的方法:

    • 增加批处理:public void addBatch(String sql) throws SQLException

    • 执行批处理:public int[] executeBatch() throws SQLException

      • 返回的数组是包含了所有批处理语句的执行结果;

  • PreparedStatment接口定义的方法:

    • 增加批处理:public void addBatch() throws SQLException

public class TestDemo {
	private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";
	private static final String USER = "scott";
	private static final String PASSWORD = "tiger";
	public static void main(String[] args) throws Exception {
		Class.forName(DBDRIVER);
		Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
		Statement stmt = conn.createStatement();
		stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试A')");
		stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试B')");
		stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试C')");
		stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试D')");
		stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试E')");
		stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试F')");
		int[] result = stmt.executeBatch(); // 执行批处理
		System.out.println(Arrays.toString(result));
		conn.close();
	}
}

如果假设以上的五条批处理属于一组关联的操作,如果中间有一条语句执行失败,其他的不应该成功。

在批处理操作的过程之中,由于JDBC具备有自动的事务提交,所以一旦中间的语句出现了错误,那么结果就是错误前的语句正常执行,错误后的语句就不执行了,很明显这不应该。

可以使用JDBC提供的事务处理操作来进行手工的事务控制,所有的操作方法都在Connection接口里定义:

  • 事务提交:public void commit() throws SQLException

  • 事务回滚:public void rollback() throws SQLException

  • 设置是否为自动提交:public void setAutoCommit(boolean autoCommit) throws SQLException

范例: 利用事务处理

public class TestDemo {
	private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";
	private static final String USER = "scott";
	private static final String PASSWORD = "tiger";
	public static void main(String[] args) throws Exception {
		Class.forName(DBDRIVER);
		Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
		Statement stmt = conn.createStatement();
		conn.setAutoCommit(false);
		try {
			stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试A')");
			stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试B')");
			stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试C')");
			stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试D')");
			stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试E')");
			stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'测试F')");
			int[] result = stmt.executeBatch(); // 执行批处理
			System.out.println(Arrays.toString(result));
			conn.commit(); // 如果没有错误进行提交
		} catch (Exception e) {
			e.printStackTrace();
			conn.rollback(); // 如果出现异常则进行回滚
		}
		conn.close();
	}
}

最后更新于