Modified:
branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java
branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java
Log:
Performance enhancement of initial character set configuration, driver
will only send commands required to configure connection character set
session variables if the current values on the server do not match
what is required.
Cleaned up logic detecting autocommit state on server.
Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java
===================================================================
--- branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java 2006-10-27 00:02:09 UTC (rev 5947)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java 2006-10-27 21:12:32 UTC (rev 5948)
@@ -2158,16 +2158,7 @@
return pStmt;
}
- /**
- * In some cases, it is desirable to immediately release a Connection's
- * database and JDBC resources instead of waiting for them to be
- * automatically released (cant think why off the top of my head) <B>Note:</B>
- * A Connection is automatically closed when it is garbage collected.
- * Certain fatal errors also result in a closed connection.
- *
- * @exception SQLException
- * if a database access error occurs
- */
+
public void close() throws SQLException {
realClose(true, true, false, null);
}
@@ -2338,23 +2329,39 @@
// versions > 4.1.0
try {
+
+ // Fault injection for testing server character set indices
+
+ if (props != null && props.getProperty("com.mysql.jdbc.faultInjection.serverCharsetIndex") != null) {
+ this.io.serverCharsetIndex = Integer.parseInt(
+ props.getProperty(
+ "com.mysql.jdbc.faultInjection.serverCharsetIndex"));
+ }
+
String serverEncodingToSet =
CharsetMapping.INDEX_TO_CHARSET[this.io.serverCharsetIndex];
if (serverEncodingToSet == null || serverEncodingToSet.length() == 0) {
- throw SQLError.createSQLException(
- "Unknown initial character set index '"
- + this.io.serverCharsetIndex
- + "' received from server. Initial client character set can be forced via the 'characterEncoding' property.",
- SQLError.SQL_STATE_GENERAL_ERROR);
+ if (realJavaEncoding != null) {
+ // user knows best, try it
+ setEncoding(realJavaEncoding);
+ } else {
+ throw SQLError.createSQLException(
+ "Unknown initial character set index '"
+ + this.io.serverCharsetIndex
+ + "' received from server. Initial client character set can be forced via the 'characterEncoding' property.",
+ SQLError.SQL_STATE_GENERAL_ERROR);
+ }
}
+ // "latin1" on MySQL-4.1.0+ is actually CP1252, not ISO8859_1
if (versionMeetsMinimum(4, 1, 0) &&
"ISO8859_1".equalsIgnoreCase(serverEncodingToSet)) {
serverEncodingToSet = "Cp1252";
}
setEncoding(serverEncodingToSet);
+
} catch (ArrayIndexOutOfBoundsException outOfBoundsEx) {
if (realJavaEncoding != null) {
// user knows best, try it
@@ -2389,10 +2396,12 @@
// charset names are case-sensitive
if (!getUseOldUTF8Behavior()) {
- execSQL(null, "SET NAMES utf8", -1, null,
- java.sql.ResultSet.TYPE_FORWARD_ONLY,
- java.sql.ResultSet.CONCUR_READ_ONLY,
- false, this.database, true, false);
+ if (!characterSetNamesMatches("utf8")) {
+ execSQL(null, "SET NAMES utf8", -1, null,
+ java.sql.ResultSet.TYPE_FORWARD_ONLY,
+ java.sql.ResultSet.CONCUR_READ_ONLY,
+ false, this.database, true, false);
+ }
}
setEncoding(realJavaEncoding);
@@ -2413,11 +2422,14 @@
*/
if (mysqlEncodingName != null) {
- execSQL(null, "SET NAMES " + mysqlEncodingName,
+
+ if (!characterSetNamesMatches(mysqlEncodingName)) {
+ execSQL(null, "SET NAMES " + mysqlEncodingName,
-1, null,
java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY,
false, this.database, true, false);
+ }
}
// Switch driver's encoding now, since the server
@@ -2433,10 +2445,12 @@
.getMysqlEncodingForJavaEncoding(getEncoding()
.toUpperCase(Locale.ENGLISH), this);
- execSQL(null, "SET NAMES " + mysqlEncodingName, -1,
+ if (!characterSetNamesMatches(mysqlEncodingName)) {
+ execSQL(null, "SET NAMES " + mysqlEncodingName, -1,
null, java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY, false,
this.database, true, false);
+ }
realJavaEncoding = getEncoding();
}
@@ -2450,11 +2464,19 @@
//
if (getCharacterSetResults() == null) {
- execSQL(null, "SET character_set_results = NULL", -1, null,
- java.sql.ResultSet.TYPE_FORWARD_ONLY,
- java.sql.ResultSet.CONCUR_READ_ONLY, false,
- this.database, true,
- false);
+
+ //
+ // Only send if needed
+ //
+
+ if (this.serverVariables.get("character_set_results") != null) {
+
+ execSQL(null, "SET character_set_results = NULL", -1, null,
+ java.sql.ResultSet.TYPE_FORWARD_ONLY,
+ java.sql.ResultSet.CONCUR_READ_ONLY, false,
+ this.database, true,
+ false);
+ }
} else {
String charsetResults = getCharacterSetResults();
String mysqlEncodingName = null;
@@ -2468,16 +2490,23 @@
.toUpperCase(Locale.ENGLISH), this);
}
- StringBuffer setBuf = new StringBuffer(
- "SET character_set_results = ".length()
- + mysqlEncodingName.length());
- setBuf.append("SET character_set_results = ").append(
- mysqlEncodingName);
-
- execSQL(null, setBuf.toString(), -1, null,
- java.sql.ResultSet.TYPE_FORWARD_ONLY,
- java.sql.ResultSet.CONCUR_READ_ONLY, false,
- this.database, true, false);
+ //
+ // Only change the value if needed
+ //
+
+ if (!mysqlEncodingName.equalsIgnoreCase(
+ (String)this.serverVariables.get("character_set_results"))) {
+ StringBuffer setBuf = new StringBuffer(
+ "SET character_set_results = ".length()
+ + mysqlEncodingName.length());
+ setBuf.append("SET character_set_results = ").append(
+ mysqlEncodingName);
+
+ execSQL(null, setBuf.toString(), -1, null,
+ java.sql.ResultSet.TYPE_FORWARD_ONLY,
+ java.sql.ResultSet.CONCUR_READ_ONLY, false,
+ this.database, true, false);
+ }
}
if (getConnectionCollation() != null) {
@@ -2508,6 +2537,15 @@
return characterSetAlreadyConfigured;
}
+ private boolean characterSetNamesMatches(String mysqlEncodingName) {
+ // set names is equivalent to character_set_client ..._results and ..._connection,
+ // but we set _results later, so don't check it here.
+
+ return (mysqlEncodingName != null &&
+ mysqlEncodingName.equalsIgnoreCase((String)this.serverVariables.get("character_set_client")) &&
+ mysqlEncodingName.equalsIgnoreCase((String)this.serverVariables.get("character_set_connection")));
+ }
+
/**
* Configures the client's timezone if required.
*
@@ -3908,10 +3946,6 @@
setTransformedBitIsBoolean(false);
}
- // We need to do this before any further data gets
- // sent to the server....
- boolean clientCharsetIsConfigured = configureClientCharacterSet();
-
this.parserKnowsUnicode = versionMeetsMinimum(4, 1, 0);
//
@@ -3970,14 +4004,8 @@
}
checkTransactionIsolationLevel();
-
- //
- // We only do this for servers older than 4.1.0, because
- // 4.1.0 and newer actually send the server charset
- // during the handshake, and that's handled at the
- // top of this method...
- //
- if (!clientCharsetIsConfigured) {
+
+ if (!versionMeetsMinimum(4, 1, 0)) {
checkServerEncoding();
}
@@ -4017,48 +4045,11 @@
this.errorMessageEncoding =
CharsetMapping.getCharacterEncodingForErrorMessages(this);
- boolean overrideDefaultAutocommit = false;
- String initConnectValue = (String) this.serverVariables
- .get("init_connect");
+ boolean overrideDefaultAutocommit = isAutoCommitNonDefaultOnServer();
+
+ configureClientCharacterSet();
- if (versionMeetsMinimum(4, 1, 2) && initConnectValue != null
- && initConnectValue.length() > 0) {
- // auto-commit might have changed
- java.sql.ResultSet rs = null;
- java.sql.Statement stmt = null;
-
- try {
- stmt = getMetadataSafeStatement();
-
- rs = stmt.executeQuery("SELECT @@session.autocommit");
-
- if (rs.next()) {
- this.autoCommit = rs.getBoolean(1);
- if (this.autoCommit != true) {
- overrideDefaultAutocommit = true;
- }
- }
-
- } finally {
- if (rs != null) {
- try {
- rs.close();
- } catch (SQLException sqlEx) {
- // do nothing
- }
- }
-
- if (stmt != null) {
- try {
- stmt.close();
- } catch (SQLException sqlEx) {
- // do nothing
- }
- }
- }
- }
-
if (versionMeetsMinimum(3, 23, 15)) {
this.transactionsSupported = true;
@@ -4137,6 +4128,68 @@
setupServerForTruncationChecks();
}
+ /**
+ * Has the default autocommit value of 0 been changed on the server
+ * via init_connect?
+ *
+ * @return true if autocommit is not the default of '0' on the server.
+ *
+ * @throws SQLException
+ */
+ private boolean isAutoCommitNonDefaultOnServer() throws SQLException {
+ boolean overrideDefaultAutocommit = false;
+
+ String initConnectValue = (String) this.serverVariables
+ .get("init_connect");
+
+ if (versionMeetsMinimum(4, 1, 2) && initConnectValue != null
+ && initConnectValue.length() > 0) {
+ if (!getElideSetAutoCommits()) {
+ // auto-commit might have changed
+ java.sql.ResultSet rs = null;
+ java.sql.Statement stmt = null;
+
+ try {
+ stmt = getMetadataSafeStatement();
+
+ rs = stmt.executeQuery("SELECT @@session.autocommit");
+
+ if (rs.next()) {
+ this.autoCommit = rs.getBoolean(1);
+ if (this.autoCommit != true) {
+ overrideDefaultAutocommit = true;
+ }
+ }
+
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException sqlEx) {
+ // do nothing
+ }
+ }
+
+ if (stmt != null) {
+ try {
+ stmt.close();
+ } catch (SQLException sqlEx) {
+ // do nothing
+ }
+ }
+ }
+ } else {
+ if (this.getIO().isSetNeededForAutoCommitMode(true)) {
+ // we're not in standard autocommit=true mode
+ this.autoCommit = false;
+ overrideDefaultAutocommit = true;
+ }
+ }
+ }
+
+ return overrideDefaultAutocommit;
+ }
+
private void setupServerForTruncationChecks() throws SQLException {
if (getJdbcCompliantTruncation()) {
if (versionMeetsMinimum(5, 0, 2)) {
Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java 2006-10-27 00:02:09 UTC (rev 5947)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java 2006-10-27 21:12:32 UTC (rev 5948)
@@ -731,7 +731,7 @@
return !inTransactionOnServer;
}
- return !autoCommitModeOnServer;
+ return autoCommitModeOnServer != autoCommitFlag;
}
return true;
| Thread |
|---|
| • Connector/J commit: r5948 - branches/branch_5_0/connector-j/src/com/mysql/jdbc | mmatthews | 27 Oct |