美文网首页
rewriteBatchedStatement配置

rewriteBatchedStatement配置

作者: kacen | 来源:发表于2021-10-08 01:46 被阅读0次

相信有过较大数据测试或者大数据处理经验的人对这个配置不陌生,为什么呢,我来给你们解释解释吧。
这一篇文章写的较为中性,所以有不足的可以提出,我可以精进修改,给需要的人了解哈!
首先,我们在处理许多业务的时候,会需要对数据的批量操作的CRUD,但是捏,问题就来了。

如何实现批量的添加,更改和删除呢?

1.for循环
2.session批量插入
3.foreach插入方式
以上三种方式呢,不管你用的哪一个,嘿嘿,只要你没有设置rewriteBatchedStatement这个参数,他都会给你一条一条的发送出去,那速度也不用说了。因为mysql的默认配置是为false。
下面我来来贴一段源代码(以更新来测试的),最后是执行到了executeBatchInternal方法:

protected long[] executeBatchInternal() throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {

        if (this.connection.isReadOnly()) {
            throw new SQLException(Messages.getString("PreparedStatement.25") + Messages.getString("PreparedStatement.26"),
                    SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
        }

        if (this.batchedArgs == null || this.batchedArgs.size() == 0) {
            return new long[0];
        }

        // we timeout the entire batch, not individual statements
        int batchTimeout = this.timeoutInMillis;
        this.timeoutInMillis = 0;

        resetCancelledState();

        try {
            statementBegins();

            clearWarnings();

            if (!this.batchHasPlainStatements && this.connection.getRewriteBatchedStatements()) {

                if (canRewriteAsMultiValueInsertAtSqlLevel()) {
                    return executeBatchedInserts(batchTimeout);
                }

                if (this.connection.versionMeetsMinimum(4, 1, 0) && !this.batchHasPlainStatements && this.batchedArgs != null
                        && this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) {
                    return executePreparedBatchAsMultiStatement(batchTimeout);
                }
            }

            return executeBatchSerially(batchTimeout);
        } finally {
            this.statementExecuting.set(false);

            clearBatch();
        }
    }
}

你用的batchUpdate最终执行就是到上面的源码,然后return的是exexuteBatchSerially,官方给他的解释是什么呢.

Executes the current batch of statements by executing them one-by-one.

然后我们进入到 exexuteBatchSerially这个方法里看一看

for (this.batchCommandIndex = 0; this.batchCommandIndex < nbrCommands; this.batchCommandIndex++) {
    Object arg = this.batchedArgs.get(this.batchCommandIndex);

    try {
        if (arg instanceof String) {
            updateCounts[this.batchCommandIndex] = executeUpdateInternal((String) arg, true, this.retrieveGeneratedKeys);

            // limit one generated key per OnDuplicateKey statement
            getBatchedGeneratedKeys(this.results.getFirstCharOfQuery() == 'I' && containsOnDuplicateKeyInString((String) arg) ? 1 : 0);
        } else {
            BatchParams paramArg = (BatchParams) arg;
            //核心代码,for循环执行每一条SQL
            updateCounts[this.batchCommandIndex] = executeUpdateInternal(paramArg.parameterStrings, paramArg.parameterStreams,
                    paramArg.isStream, paramArg.streamLengths, paramArg.isNull, true);

            // limit one generated key per OnDuplicateKey statement
            getBatchedGeneratedKeys(containsOnDuplicateKeyUpdateInSQL() ? 1 : 0);
        }
    } catch (SQLException ex) {
        updateCounts[this.batchCommandIndex] = EXECUTE_FAILED;

        if (this.continueBatchOnError && !(ex instanceof MySQLTimeoutException) && !(ex instanceof MySQLStatementCancelledException)
                && !hasDeadlockOrTimeoutRolledBackTx(ex)) {
            sqlEx = ex;
        } else {
            long[] newUpdateCounts = new long[this.batchCommandIndex];
            System.arraycopy(updateCounts, 0, newUpdateCounts, 0, this.batchCommandIndex);

            throw SQLError.createBatchUpdateException(ex, newUpdateCounts, getExceptionInterceptor());
        }
    }
}

上面我标明的位置,可以看到源码上写的也是,sql是一条一条的传送到服务器的,而不是batch的形式。

然后我们回到一开始的executeBatchInternal这个类里看一看,想要进入到batch是有条件的
image.png
batchHasPlainStatements是默认false的,然后决定性的就是后面的条件this.connection.getRewriteBatchedStatements()这个开关,这个开关也就是我们在配置的时候rewriteBatchedStatement这个参数是否配置为true。如果为true的情况下,它就会重新给你通过切割重组(源码就是这么个样)然后拼成一串比较长而且骚的sql,哈哈哈哈,然后发送给服务器.(但是官方默认为false也是有原因的,因为怕有些语句没有办法进行重组,导致一些小问题,大家都知道这种东西很*蛋。)

结尾再给你们补一下小知识点

这个是什么呢,就是它的批量的数量是有要求的,如果没有达到要求,它还是一条一条走的,就在刚才的源码上就能看到了


image.png

看了这里都知道啦,基本讲完。

相关文章

  • rewriteBatchedStatement配置

    相信有过较大数据测试或者大数据处理经验的人对这个配置不陌生,为什么呢,我来给你们解释解释吧。这一篇文章写的较为中性...

  • MySQL批处理之rewriteBatchedStatement

    网上很多文章,都说MySQL驱动并没有实现"真正的"batchUpdate,执行的时候还是一条一条按顺序将SQL发...

  • Kafka常用资料

    配置大全 Broker配置Topic配置生产者配置消费者配置Stream配置Connect配置AdminClien...

  • 升级hue需要配置的模块

    Sentry配置 hue配置 hive配置 HDFS配置

  • Openstack学习笔记(二):基础配置

    基础服务配置 基础服务配置主要分为以下几步: 网络配置 配置yum源 配置主机名 SELINUX配置 NTP配置 ...

  • thinkphp5学习笔记(二)配置文件

    配置文件 配置文件格式 场景配置 模块配置 加载其他位置的配置文件 如何正确读取配置项 动态配置 如何正确设置配置...

  • 框架代码学习

    web.xml配置 数据库配置 webservice配置 mvc配置 orm配置 菜单和权限配置 mvc、orm、...

  • 微信小程序JSON配置

    全局配置 ( app.json ) 配置页面文件 配置navigationBar样式 配置tabBar 页面配置 ...

  • ceph部署

    初始配置 配置源 安装 OSD配置 cgr配置 验证:

  • 微信小程序的配置详解

    app的页面配置app的窗口配置app的tabBar配置网络超时配置及debug开启配置页面配置配置·小程序 ht...

网友评论

      本文标题:rewriteBatchedStatement配置

      本文链接:https://www.haomeiwen.com/subject/zjetoltx.html