首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在useServerPrepStmts连接器/J中将cachePrepStmts和MySQL设置为true时,“执行”之前的冗余“重置stmt”

在useServerPrepStmts连接器/J中将cachePrepStmts和MySQL设置为true时,“执行”之前的冗余“重置stmt”
EN

Stack Overflow用户
提问于 2022-04-22 10:37:52
回答 1查看 81关注 0票数 0

我使用MySQL Connector/J (版本8.0.28)作为客户端的驱动程序。以下是我用于测试的代码的一部分:

代码语言:javascript
运行
复制
PreparedStatement ps = null;
String url = "jdbc:mysql://10.86.49.16:3306/test?useServerPrepStmts=true&cachePrepStmts=true";
...
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
String sql = "select * from test where id=?";
for (int i = 1; i <= 3; i++) {
    ps = conn.prepareStatement(sql);
    ps.setInt(1, i);
    ps.execute();
    ps.close();
}

单独设置"useServerPrepStmts=true“时,我的一般日志如下所示:

代码语言:javascript
运行
复制
6 Prepare   select * from test where id=?
6 Execute   select * from test where id=1
6 Close stmt
6 Prepare   select * from test where id=?
6 Execute   select * from test where id=2
6 Close stmt
6 Prepare   select * from test where id=?
6 Execute   select * from test where id=3
6 Close stmt

但是,在一起启用"cachePrepStmts“()之后,日志变成:

代码语言:javascript
运行
复制
7 Prepare   select * from test where id=?
7 Execute   select * from test where id=1
7 Reset stmt
7 Execute   select * from test where id=2
7 Reset stmt
7 Execute   select * from test where id=3

看来准备好的语句缓存确实生效了,但是有意外的“重置stmt”,这会导致额外的往返。我检查了MySQL连接器/J的源代码,并在关闭准备好的语句时发现了执行的奇怪逻辑。它将总是将longParameterSwitchDetected设置为真正的,在我的例子中是!

代码语言:javascript
运行
复制
com.mysql.cj.ServerPreparedQuery#clearParameters

/**
 * @param clearServerParameters
 *            flag indicating whether we need an additional clean up
 */
public void clearParameters(boolean clearServerParameters) {
    boolean hadLongData = false;
    if (this.queryBindings != null) {
        hadLongData = this.queryBindings.clearBindValues();
        this.queryBindings.setLongParameterSwitchDetected(clearServerParameters && hadLongData ? false : true);
    }
    ...
}

然后,当下一个"Execute“出现时,它将检查此标志并决定是否发送"Reset stmt”,如下所示:

代码语言:javascript
运行
复制
com.mysql.cj.ServerPreparedQuery#prepareExecutePacket

public NativePacketPayload prepareExecutePacket() {
    ServerPreparedQueryBindValue[] parameterBindings = this.que
    if (this.queryBindings.isLongParameterSwitchDetected()) {
        ...
        // Okay, we've got all "newly"-bound streams, so reset server-side state to clear out previous bindings
        serverResetStatement();
    }
    ...
}

我尝试在调试模式下手动将此longParameterSwitchDetected设置为false,并在没有发送“重置stmt”的情况下成功执行该语句。以下是我的问题:

是否有任何用于删除此“重置stmt"?

  • What's”的配置-- "longParameterSwitchDetected"?

的确切含义/逻辑

EN

回答 1

Stack Overflow用户

发布于 2022-04-24 10:19:40

这实际上是MySQL连接器/J中的一个代码错误,在与作者接触之后。我已经向社区报告过了。请参阅https://bugs.mysql.com/bug.php?id=107107

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71967394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档