JDBC事务和批处理

事务

在MySQL中事务是将多个dml语句当作一个整体进行处理

-- 开始事务
START TRANSACTION
-- 设置保存点1
SAVEPOINT a
-- 执行dml操作
INSERT INTO test1 VALUES(1,'tom')
-- 设置保存点2
SAVEPOINT b
INSERT INTO test1 VALUES(2,'smith')
-- 回滚事务
ROLLBACK TO b
ROLLBACK TO a
commit -- 提交事务所有的操作生效,不能回退

注意细节

1.如果不开始事务,他会自动提交

2.如果没有创建保存点,rollback会回退到事务开始的状态

JDBC中当一个Connection对象创建时,默认情况下是自动提交事务,每次执行一个sql语句,如果执行成功,就会向数据库自动提交,而不能回滚

1.调用setAutoCommit(false)可以取消自动提交事务

2.所有sql语句执行完后,调用commit()方法进行提交

3.在其中某个操作失败时,调用rollback()进行回滚

 try {
            connection = JDBCUtils.getConnection(); // 在默认情况下,connection是默认自动提交
            //将 connection 设置为不自动提交
            connection.setAutoCommit(false); //开启了事务
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate(); // 执行第1条sql
 
            int i = 1 / 0; //假如这里出现异常会走到catch中去
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate(); // 执行第3条sql
 
            //这里提交事务
            connection.commit();
 
        } catch (Exception e) {
            //这里我们可以进行回滚,即撤销执行的SQL
            //默认回滚到事务开始的状态.
            System.out.println("执行发生了异常,撤销执行的sql");
            try {
                connection.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            e.printStackTrace();
}

批处理

当需要成批插入或更新记录时,可以使用Java的批处理更新机制,通常情况下比单独处理更有效率

1.addBatch()添加需要处理的sql语句或者参数

2.executeBatch():执行语句

3.clearBatch()清空批处理语句

4.在url中加入参数

rewriteBatchedStatements = true

public void batch() throws Exception {
 
        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into admin2 values(null, ?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        System.out.println("开始执行");
        long start = System.currentTimeMillis();//开始时间
        for (int i = 0; i < 5000; i++) {//5000执行
            preparedStatement.setString(1, "jack" + i);
            preparedStatement.setString(2, "111");
            preparedStatement.addBatch();
            //当有1000条记录时,在批量执行
            if((i + 1) % 1000 == 0) {//满1000条sql
                preparedStatement.executeBatch();
                //清空一把
                preparedStatement.clearBatch();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("批量方式 耗时=" + (end - start));//批量方式 耗时=108
        //关闭连接
        JDBCUtils.close(null, preparedStatement, connection);
    }

public void noBatch() throws Exception {
 
        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into admin2 values(null, ?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        System.out.println("开始执行");
        long start = System.currentTimeMillis();//开始时间
        for (int i = 0; i < 5000; i++) {//5000执行
            preparedStatement.setString(1, "jack" + i);
            preparedStatement.setString(2, "666");
            preparedStatement.executeUpdate();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统的方式 耗时=" + (end - start));//传统的方式 耗时=10702
        //关闭连接
        JDBCUtils.close(null, preparedStatement, connection);
    }

 模拟了传统方法和预处理之间的时间消耗差异

源码

1. 创建 ArrayList - elementData => Object[]
2. elementData => Object[] 就会存放我们预处理的sql语句
3. 当elementData满后,就按照1.5扩容
4. 当添加到指定的值后,就executeBatch
5. 批量处理会减少我们发送sql语句的网络开销,而且减少编译次数,因此效率提高

public void addBatch() throws SQLException {
                synchronized(this.checkClosed().getConnectionMutex()) {
                    if (this.batchedArgs == null) {
                        this.batchedArgs = new ArrayList();
                    }
                    for(int i = 0; i < this.parameterValues.length; ++i) {
                        this.checkAllParametersSet(this.parameterValues[i], this.parameterStreams[i], i);
                    }
                    this.batchedArgs.add(new PreparedStatement.BatchParams(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths, this.isNull));
                }
 }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值