JDBC之事务、批量处理

事务的4个特性:

/*
    tips:
    原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

*/

数据库事务使用过程:

/**
     JDBC 数据库事务操作
     1、开启事务:connection.setAutoCommit(false)
     2、提交事务:connection.commit()
     3、回滚事务:connection.rollback()

     注意:若多个操作使用同一个事务, 则他们需要使用同一个 Connection 对象!

    使用样板:
    try{ 
        //1. 获取连接
        //2. 开启事务 connection.setAutoCommit(false);
        //3. 调用 DAO 方法完成操作
        //4. 没有任何异常, 则提交事务 connection.commit();
    }catch(Exception ex){ 
         //5. 出异常,回滚事务 connection.rollback(); }
    finally{ //6. 关闭连接 connection.close(); }



     */
    @Test
    public void testTransaction() throws SQLException, Exception {
        // 完成 tom 给 jerry 的转账操作.
        // 1. tom 余额减除 500
        // 2. jerry 余额加上 500

        QueryRunner queryRunner = new QueryRunner();

        Connection connection = null;

        try {
            // 1. 获取连接
            connection = JdbcUtils.getConnection();
            // 2. 开启事务: 默认情况下, 事务是自动提交的, 需要修改为手动提交
            connection.setAutoCommit(false);

            // 3. 执行操作
            String sql = "UPDATE users SET balance = balance + ? WHERE username = ?";
            queryRunner.update(connection, sql, -500, "tom");
            // 模拟异常
            System.out.println(10 / 10);
            queryRunner.update(connection, sql, 500, "jerry");

            // 4. 若没有异常, 则提交事务
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();

            // 5. 若有异常, 则回滚事务
            connection.rollback();
        } finally {
            // 6. 关闭连接
            DbUtils.closeQuietly(connection);
        }

        // 两个操作都成功才算成功, 若有一个失败, 都不能完成操作
    }

=============================

批量处理:
先使用statement插入1w条数据并记录执行时间

/*
    tips:
    拼接字符串
    excute(String sql):执行增删改查操作


*/
       // 1. 使用 Statement 进行插入1w条数据
        Connection connection = null;
        Statement statement = null;

        long begin = System.currentTimeMillis();

         try {
         connection = JdbcUtils.getConnection();
         String sql = null;
         statement = connection.createStatement();

         for(int i = 0; i < 10000; i++){
         sql = "INSERT INTO customers2 VALUES(" + i + ",'LastName_" + i +
         "','email_" + i + "@atguigu.com'," + (i%99) +")";//拼接字符串
         statement.execute(sql);
         }
         } catch (Exception e) {
         e.printStackTrace();
         } finally{
         DbUtils.closeQuietly(connection);
         }
         long end = System.currentTimeMillis();
        System.out.println("time:" + (end - begin)); //执行时间为 8046秒 
    }
/*
    tips:
    excute():执行增删改查操作,注意和statement的执行方法区分开

*/
        /*
        2、使用 PreparedStatement 进行插入

         PreparedStatement preparedStatement = null;
         try {
         connection = JdbcUtils.getConnection();
         String sql = "INSERT INTO customers2 VALUES(?,?,?,?)";
         preparedStatement = connection.prepareStatement(sql);

         for(int i = 0; i < 10000; i++){
         preparedStatement.setObject(1, i);
         preparedStatement.setObject(2, "LastName_" + i);
         preparedStatement.setObject(3, "email_" + i + "@atguigu.com");
         preparedStatement.setObject(4, (i % 99));

         preparedStatement.execute();//执行操作
         }
         } catch (Exception e) {
         e.printStackTrace();
         }finally {
            DbUtils.closeQuietly(preparedStatement);
            DbUtils.closeQuietly(connection);
        }

        long end = System.currentTimeMillis();
        System.out.println("time:" + (end - begin)); // 执行时间为2987秒
    }

使用 PreparedStatement 进行批量插入1w条数据并记录执行时间:

/*

    addBatch():积攒批量插入的数量
    executeBatch():执行批量插入
    clearBatch():清理缓存

*/
        PreparedStatement preparedStatement = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "INSERT INTO customers2 VALUES(?,?,?,?)";
            preparedStatement = connection.prepareStatement(sql);

            long totalCount = 10195;

            for (int i = 0; i < totalCount; i++) {
                preparedStatement.setObject(1, i);
                preparedStatement.setObject(2, "LastName_" + i);
                preparedStatement.setObject(3, "email_" + i + "@atguigu.com");
                preparedStatement.setObject(4, (i % 99));

                // "积攒"
                preparedStatement.addBatch();

                if ((i + 1) % 300 == 0) {
                    //批量执行
                    preparedStatement.executeBatch();
                    //清理缓存
                    preparedStatement.clearBatch();
                }
            }

            if (totalCount % 300 != 0) {
                preparedStatement.executeBatch();
                // 最后一次可以不清理缓存, 因为后面就直接关闭了.
                // preparedStatement.clearBatch();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(preparedStatement);
            DbUtils.closeQuietly(connection);
        }

        long end = System.currentTimeMillis();
        System.out.println("time:" + (end - begin)); // 执行时间为:365秒
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值