JDBC(6)事务处理&批量处理

时间:2022-12-20 12:02:53

事务处理就是当执行多个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执行的速度快