3

我遇到了 MySQL db 的问题,即使没有自动提交模式更改,也会多次记录 setAutocommit。例如,如果我调用 setautocommit(false) 5 次,我会在查询日志中看到 5 个查询说 set autommit=0;

这通常不应该发生,因为自动提交模式没有改变。仅当我更改自动提交模式时才应发送查询,即说 1 到 0。

当我查看 MySQL 连接类实现时,我发现他们检查 useLocalSessionState 值来决定是否要执行查询?

 if ((getUseLocalSessionState()) && (this.autoCommit == autoCommitFlag)) {
            needsSetOnServer = false;
          }

因此,即使 this.autocommit 和 autocommit 标志相同,也不会将 needsSetOnServer 设置为 false,因为 useLocalSessionState 默认为 false。

在我的连接 URL 中添加 useLocalSessionState = true 后,我看不到不必要的查询日志。

所以,我的问题是:

  1. useLocalSessionState 的意义是什么?为什么普遍使用?
  2. 设置 useLocalSessionState = true 是否安全?

PS:我看到 SQL Server 在没有任何此类依赖项的情况下处理这种情况,即(来自 SQLServerConnection 的代码片段

if (paramBoolean == this.databaseAutoCommitMode) {
      return;
    }
4

1 回答 1

4

参考http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html

驱动程序是否应该参考 Connection.setAutoCommit() 和 Connection.setTransactionIsolation() 设置的自动提交和事务隔离的内部值以及协议维护的事务状态,而不是查询数据库或盲目地向数据库发送命令commit() 或 rollback() 方法调用?

我对此的解释(在查看 MySQL JDBC 驱动程序的代码之后)是,它不是发出例如 a SELECT @@session.tx_read_only,而是检查readOnly连接类的属性:

ConnectionImpl.java(MySQL JDBC 连接器 5.1.31):

public boolean isReadOnly() throws SQLException {
    return this.isReadOnly(true);
}

public boolean isReadOnly(boolean useSessionStatus) throws SQLException {
    if(useSessionStatus && /*...*/ && !this.getUseLocalSessionState()) {
        //...

        rs = stmt.executeQuery("select @@session.tx_read_only");

        //...
    } else {
        return this.readOnly;
    }
}

此外,如果 useLocalSessionState 为 false,它只会发出用于设置只读状态的 SQL 命令:

public void setReadOnlyInternal(boolean readOnlyFlag) throws SQLException {
    if((/*...*/ !this.getUseLocalSessionState()) {
        this.execSQL((StatementImpl)null, "set session transaction " + (readOnlyFlag?"read only":"read write"), -1, (Buffer)null, 1003, 1007, false, this.database, (Field[])null, false);
    }

    this.readOnly = readOnlyFlag;
}

我假设这同样适用于自动提交和事务隔离级别属性。

于 2014-12-28T13:57:35.587 回答