MySQL进阶(事务)——转账事务的问题 COMMIT,ROLLBACK & 百万条数据插入的性能调优=3万次提交变成1次_mysql commit和rollback的实验

此时,执行sql语句,并没有自动提交,数据库数据不变化,当执行commit提交之后,数据库数据才变化。

在这里插入图片描述

例子:网络中断了

模拟转账的时候,出现网络中断的情况,此时由于关闭了事务自动提交,因此,数据库的数据还没有更新

在这里插入图片描述
数据库的数据还没变化

在这里插入图片描述
然后rollback回滚,再手动提交,数据库就回滚了。

在这里插入图片描述

例子:自动提交模式下失效

在这里插入图片描述

在自动提交模式下,rollback命令失效

在这里插入图片描述

程序实现

程序

需要文中资料的朋友,可以加我\/信获取:vip1024b 备注Java

中来实现。 mysql存储引擎必须是innodb, 否则不支持事务

package com.tianju;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/\*\*
 \* 模拟转账业务
 \*/
public class SQLTestDemo {
    public static void main(String[] args) throws SQLException {
        String url = "jdbc:mysql://localhost:3306/car\_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8";
        Connection conn = DriverManager.getConnection(url, "root", "123");
        // 手动关闭自动提交事务
        conn.setAutoCommit(false);
        try {
            PreparedStatement cmd1 = conn.prepareStatement("update `user` set money = money - 1000 where cardId = 1");
            cmd1.executeUpdate();

            // 模拟网络故障问题
            System.out.println(5 / 0);

            PreparedStatement cmd2 = conn.prepareStatement("update `user` set money = money + 1000 where cardId = 2");
            cmd2.executeUpdate();

            System.out.println("转账成功!!");
            conn.commit(); // 提交事务,让数据真正的持久化。(同时也不能回滚了!!!)

        } catch (Exception e) {
            System.out.println("转账失败.....");
            e.printStackTrace();
            // 回滚
            conn.rollback();
            System.out.println("事务已经回滚成功了.....");
        } finally {

            conn.setAutoCommit(true); //手动把自动提交事务打开,因为我们这个业务比较特殊,所以只是临时用一下而已。。。
            conn.close();  // 关闭连接
        }
    }
}

查看一下系统所支持的引擎类型

SHOW ENGINES

在这里插入图片描述

转账失败,捕获异常,事务回滚

在这里插入图片描述

百万数据的性能调优

SHOW VARIABLES LIKE ‘autocommit’;

自动提交已经打开

在这里插入图片描述

假设现在要插入30000条,3万条数据,对比不同提交方式下的性能

1.逐条提交

在这里插入图片描述

2.积攒一批提交

在这里插入图片描述

3.变成1次提交

在这里插入图片描述

package com.tianju;

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

/\*\*
 \* 性能调优演示
 \*/
public class TimeTestDemo {
    // 添加10万条数据到user表
    // 一条一条添加,总共耗时:74232
    // 每执行一条SQL语句,就和数据据交互
    // 解决方案:批量执行SQL语句
    public static void v1() throws SQLException {
        String url = "jdbc:mysql://localhost:3306/car\_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8";
        Connection conn = DriverManager.getConnection(url, "root", "123");
        PreparedStatement cmd = conn.prepareStatement("insert into user values(? , ?)");
        int count = 30000;
        // 大忌:尽量避免在循环里面访问数据库.....
        for (int i = 1; i <= count ; i++) {
            cmd.setObject(1,i);
            cmd.setObject(2, 1000);
            cmd.executeUpdate();
        }
        conn.close();
    }


    /\*\*
 \* 第二个版本,批量执行SQL
 \* 总共耗时:130346
 \* @throws SQLException
 \*/
    public static void v2() throws SQLException {
        String url = "jdbc:mysql://localhost:3306/car\_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8";
        Connection conn = DriverManager.getConnection(url, "root", "123");
        PreparedStatement cmd = conn.prepareStatement("insert into user values(? , ?)");
        int count = 30000;
        // 大忌:尽量避免在循环里面访问数据库.....
        for (int i = 1; i <= count ; i++) {
            cmd.setObject(1,i);
            cmd.setObject(2, 1000);
            cmd.addBatch(); // 积攒SQL,把SQL堆在一起
            if (i % 2000 == 0) { //优化算法,每积攒到2000条SQL的时候,批量执行一次
                cmd.executeBatch(); // 批量执行一堆SQL
                cmd.clearBatch(); // 清空SQL缓存
            }
        }
        conn.close();
    }


    // 终极版本。
    // 每更新一条数据,会自动提交事务。(提交很影响性能!!)
    // 一共要提交3万次事务.........
    // 要把3万次事务,变成1次!!
    // 总共耗时:5885 , 放到上百万的服务器,几毫秒
    public static void v3() throws SQLException {
        String url = "jdbc:mysql://localhost:3306/car\_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8";
        Connection conn = DriverManager.getConnection(url, "root", "123");
        conn.setAutoCommit(false);
        PreparedStatement cmd = conn.prepareStatement("insert into user values(? , ?)");
        int count = 30000;
        // 大忌:尽量避免在循环里面访问数据库.....
        for (int i = 1; i <= count ; i++) {
            cmd.setObject(1,i);
            cmd.setObject(2, 1000);
            cmd.executeUpdate();
        }
        conn.commit();
        conn.setAutoCommit(true);


# 最后总结

## ActiveMQ+Kafka+RabbitMQ学习笔记PDF

![image.png](https://img-blog.csdnimg.cn/img_convert/7a9dee7e661bd085d6563f9f11a9e983.webp?x-oss-process=image/format,png)


* ### RabbitMQ实战指南

![image.png](https://img-blog.csdnimg.cn/img_convert/ea661bad3643b911928f1af67d4b0d39.webp?x-oss-process=image/format,png)


* ### 手写RocketMQ笔记

![image.png](https://img-blog.csdnimg.cn/img_convert/04d05a876d99f86ef0c9f45759e6482b.webp?x-oss-process=image/format,png)


* ### 手写“Kafka笔记”

![image](https://img-blog.csdnimg.cn/img_convert/af93d11595e95a71773ce91be70bcc72.webp?x-oss-process=image/format,png)

关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦
a-1716342406903)]


* ### 手写“Kafka笔记”

[外链图片转存中...(img-HO18w35t-1716342406903)]

关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值