JDBC(6)事务处理&批量处理
事务处理就是当执行多个SQL指令,因某个指令有误,则取消执行所有的命令
它的作用是保证各项的完整性和一致性
JDBC的数据操作时
commit():提交事务
rollback():回退事务
绝位于java.sql.Connection接口类中
JDBC中的事务操作时默认提交的
可用setAutoCommit(false)来禁止自动提交
Java API中的JDBC事务是通过Connection对象进行控制的
提供了两种方式:自动提交模式&手动提交模式
默认是自动提交模式
事务处理:
public void updata1(Connection conn,String sql){ Statement statement = null; try { conn = getConnection(); statement = (Statement) conn.createStatement(); statement.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally{ JdbcTools.Close(null, statement, null); } }
@Test public void test() { Connection conn = null; try { conn = JdbcTools.getConnection(); //开始事物,取消默认提交 conn.setAutoCommit(false); String sql = "update student set sclass = " + "sclass-100 where id = 17"; updata1(conn, sql); int i = 10 / 0; System.out.println(i); sql = "update student set sclass = " + "sclass-100 where id = 18"; updata1(conn, sql); //提交事物 conn.commit(); } catch (Exception e) { e.printStackTrace(); //如出现异常,回滚事物 try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } }finally{ Close(null, null, conn); }
分析代码:很明显可以看到,代码中出现int i= 10 / 0;在进行打印,此时出错了
此时不会因为一个错误而导致之前的操作失败,上一个插入语句可以成功执行
以上对事务的简单解读
测试事物的级别:
Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE. Oracle 默认的事务隔离级别为: READ COMMITED
Mysql 支持 4 中事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ
@Test public void JiBie(){ Connection conn = null; try { conn = JdbcTools.getConnection(); //开始事物,取消默认提交 conn.setAutoCommit(false); String sql = "update student set sclass = " + "sclass-100 where id = 17"; Level(sql); //提交事物 conn.commit(); } catch (Exception e) { e.printStackTrace(); }finally{ Close(null, null, conn); } }
public void Level(String sql){ Connection conn = null; Statement statement = null; try { conn = getConnection(); //设置级别 conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); statement = (Statement) conn.createStatement(); statement.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally{ Close(null, statement, conn); } }
批量处理:
批量对数据库进行大量的操作 PreparedStatement
@Test public void testPiLiangPreparedStatement() { Connection conn = null; PreparedStatement preparedstatement = null; String sql = null; try { conn = getConnection(); conn.setAutoCommit(false); sql = "insert into student(sname,sclass) values(?,?)"; preparedstatement = (PreparedStatement) conn.prepareStatement(sql); // 开始时间 long begin = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { preparedstatement.setString(1, "name" + i); preparedstatement.setInt(2, 1234 + i); preparedstatement.executeUpdate(); //对时间进行大度的优化 //积攒 preparedstatement.addBatch(); //当积攒到一定的成都自动进行清空 if(( i + 1) % 300 == 0){ preparedstatement.executeBatch(); preparedstatement.clearBatch(); } } //若总条数不再是批量的整数倍,还需要再次进行清理 if(10 % 300 != 0){ preparedstatement.executeBatch(); preparedstatement.clearBatch(); } // 结束时间 long end = System.currentTimeMillis(); System.out.println(end - begin); conn.commit(); } catch (Exception e) { e.printStackTrace(); conn.rollback(); } finally { Close(null, preparedstatement, conn); } }
Statement
// 批量对数据库进行大量的操作 // Statement @Test public void testPiLiangStatement() { Connection conn = null; Statement statement = null; String sql = null; try { conn =getConnection(); conn.setAutoCommit(false); statement = (Statement) conn.createStatement(); // 开始时间 long begin = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { sql = "insert into student(sname,sclass) values('" + 123 + " ','" + (i + 1) + "')"; statement.executeUpdate(sql); } // 结束时间 long end = System.currentTimeMillis(); System.out.println(end - begin); conn.commit(); } catch (Exception e) { e.printStackTrace(); conn.rollback(); } finally { Close(null, statement, conn); } }
两者在插入相同的数据量之后,进行时间的对比
PreparedStatement显然比Statement执行的速度快