我遇到了MySQL数据库的问题,即使没有自动提交模式更改,也会多次记录setAutocommit。例如,如果我调用setautocommit(false)5次,我会在查询日志中看到5个查询,说set autommit = 0;
这通常不应该发生,因为自动提交模式没有改变。只有在我更改自动提交模式时才应发送查询,即说1到0。
当我查看MySQL连接类实现时,我认为他们检查useLocalSessionState值来决定是否要执行查询?
if ((getUseLocalSessionState()) && (this.autoCommit == autoCommitFlag)) {
needsSetOnServer = false;
}
所以,即使这个。自动提交& selfocommit标志相同,needsSetOnServer未设置为false因为useLocalSessionState默认为false。
在我的连接URL中添加useLocalSessionState = true后,我看不到不必要的查询日志。
所以,我的问题是:
PS:我看到SQL Server处理这种情况没有任何这种依赖,即(SQLServerConnection的代码片段
if (paramBoolean == this.databaseAutoCommitMode) {
return;
}
答案 0 :(得分:2)
参考http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html:
驱动程序是否应该引用由协议维护的Connection.setAutoCommit()和Connection.setTransactionIsolation()以及事务状态设置的autocommit和事务隔离的内部值,而不是查询数据库或盲目地发送命令commit()或rollback()方法调用的数据库?
我对此的解释(在查看MySQL JDBC驱动程序的代码之后)是代替例如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;
}
我认为这同样适用于自动提交和事务隔离级别属性。