IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL攻略 - JDBC事务案例,批处理案例分析介绍 -> 正文阅读

[大数据]MySQL攻略 - JDBC事务案例,批处理案例分析介绍

事务

基本介绍

  1. JDBC程序中当一个Connection对象创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。
  2. JDBC程序中为了多个SQL语句作为一个整体执行,需要使用事务
  3. 调用Connection 的 setAutoCommit(false)可以取消自动提交事务
  4. 在所有的SQL语句都成功执行后,调用Connection 的 commit();方法提交事务
  5. 在其中某个操作失败或出现异常时,调用rollback();方法回滚事务

模拟JDBC账户转账(无事务回滚)

原表

请添加图片描述

运行代码

模拟id 100 用户向 id 200用户转账100元

package com.taotao.jdbc.transaction_;

import com.mysql.cj.protocol.Resultset;
import com.taotao.jdbc.utils.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Create By 刘鸿涛
 * 2022/3/3 18:07
 * 演示JDBC中如何使用事务
 */
@SuppressWarnings({"all"})
public class Transaction_ {

    //模拟双方转账
    @Test
    public void noTransaction(){
        //1.得到连接
        Connection connection = null;	

        //2.组织一个sql
        String sql = "update account set money = money - 100 where id = 100";
        String sql2 = "update account set money = money + 100 where id = 200";

        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        //3.创建PreparedStatement 对象
        try {
            //
            connection = JDBCUtils.getConnection();	//默认情况下,connection是默认自动提交

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate();//执行第一条sql语句

            int i = 1 / 0; //抛出异常
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate();//执行第二条sql语句
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            JDBCUtils.close(null,preparedStatement,connection);
        }
    }
}

抛出异常

请添加图片描述

运行转账代码后的表

800减了100,但是1800并没有变成1900

请添加图片描述

结论

  • 不安全
  • 代码中途异常,但是前面的任务已经提交

事务解决转账问题

代码

package com.taotao.jdbc.transaction_;

import com.taotao.jdbc.utils.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Create By 刘鸿涛
 * 2022/3/3 18:07
 * 演示JDBC中如何使用事务
 */
@SuppressWarnings({"all"})
public class Transaction_ {

    //模拟双方转账
    @Test
    public void useTransaction(){
        //1.得到连接
        Connection connection = null;

        //2.组织一个sql
        String sql = "update account set money = money - 100 where id = 100";
        String sql2 = "update account set money = money + 100 where id = 200";

        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        //3.创建PreparedStatement 对象
        try {
            //
            connection = JDBCUtils.getConnection();
            //将 connection设置为不自动提交
            connection.setAutoCommit(false);    //设置不自动提交

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate();//执行第一条sql语句

            int i = 1 / 0; //抛出异常
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate();//执行第二条sql语句

            //这里提交事务
            connection.commit();
        } catch (Exception e) {
            //这里我们可以进行回滚,即撤销执行的SQL
            //默认回滚到事务开始状态
            System.out.println("执行发生了异常,撤销执行的sql");

            try {
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }

            e.printStackTrace();
        } finally {
            //关闭资源
            JDBCUtils.close(null,preparedStatement,connection);
        }
    }
}

结论

如果不报异常,那么双方转账成功,否则双方金钱都不会变化

得到connection后,直接调用setAutoCommit方法

只要catch住异常,就回滚

批处理

基本介绍

  1. 当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交数据库批量处理。通常情况下比单独提交处理更有效率。
  2. JDBC的批处理语句包括下面方法:
  • addBatch():添加需要批处理的SQL语句或参数
  • executeBatch():执行批量处理语句
  • clearBatch():清空批处理包的语句
  1. JDBC连接MySQL时,如果要使用批处理功能,请在url中加参数
  • rewriteBatchedStatements = true
  1. 批处理往往和PreparedStatement一起搭配使用,可以减少编译次数,又减少运行次数,效率大大提高

未使用批处理(添加5000条数据)

请添加图片描述

代码案例

package com.taotao.jdbc.batch;

import com.taotao.jdbc.utils.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * Create By 刘鸿涛
 * 2022/3/3 19:29
 */
@SuppressWarnings({"all"})
public class Batch_ {

    //传统方法,添加5000条数据到admin
    @Test
    public void noBatch() throws SQLException {
        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into admin values(?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //开始时间
        System.out.println("开始执行");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++){
            preparedStatement.setString(1,"tao" + i);
            preparedStatement.setString(2,"666");
            preparedStatement.executeUpdate();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统的sql耗时:" + (end - start));
        //关闭连接
        JDBCUtils.close(null,preparedStatement,connection);
    }
}

使用批处理(添加5000条数据)

请添加图片描述

代码案例

package com.taotao.jdbc.batch;

import com.taotao.jdbc.utils.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * Create By 刘鸿涛
 * 2022/3/3 19:29
 */
@SuppressWarnings({"all"})
public class Batch_ {

    //传统方法,添加5000条数据到admin
    @Test
    public void Batch() throws SQLException {
        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into admin values(?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //开始时间
        System.out.println("开始执行");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++){
            preparedStatement.setString(1,"tao" + i);
            preparedStatement.setString(2,"666");
            //将sql 语句加入到批处理包中 -> 看源码
            preparedStatement.addBatch();
            //当有1000条记录时,在批量执行
            if ((i + 1) % 1000 == 0){
                preparedStatement.executeBatch();
                //清空一把
                preparedStatement.clearBatch();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("批处理的sql耗时:" + (end - start));
        //关闭连接
        JDBCUtils.close(null,preparedStatement,connection);
    }
}

注意

  • 配置文件添加

    ?rewriteBatchedStatements=true

结论

  • 批处理执行sql语句速度快了进百倍左右
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:39:43  更:2022-03-04 15:39:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:51:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码