1. 程式人生 > >JDBC(6)事務處理&批量處理

JDBC(6)事務處理&批量處理

finally sys comm ted 結束時間 lose 對比 ack try

事務處理就是當執行多個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執行的速度快

JDBC(6)事務處理&批量處理