📄 connectionimpl.java
字号:
// to send our // queries from now on.... String mysqlEncodingName = CharsetMapping .getMysqlEncodingForJavaEncoding(getEncoding() .toUpperCase(Locale.ENGLISH), this); if (dontCheckServerMatch || !characterSetNamesMatches(mysqlEncodingName)) { execSQL(null, "SET NAMES " + mysqlEncodingName, -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.database, null, false); } realJavaEncoding = getEncoding(); } } // // We know how to deal with any charset coming back from // the database, so tell the server not to do conversion // if the user hasn't 'forced' a result-set character set // String onServer = null; boolean isNullOnServer = false; if (this.serverVariables != null) { onServer = (String)this.serverVariables.get("character_set_results"); isNullOnServer = onServer == null || "NULL".equalsIgnoreCase(onServer) || onServer.length() == 0; } if (getCharacterSetResults() == null) { // // Only send if needed, if we're caching server variables // we -have- to send, because we don't know what it was // before we cached them. // if (!isNullOnServer) { execSQL(null, "SET character_set_results = NULL", -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.database, null, false); if (!this.usingCachedConfig) { this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, null); } } else { if (!this.usingCachedConfig) { this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, onServer); } } } else { String charsetResults = getCharacterSetResults(); String mysqlEncodingName = null; if ("UTF-8".equalsIgnoreCase(charsetResults) || "UTF8".equalsIgnoreCase(charsetResults)) { mysqlEncodingName = "utf8"; } else { mysqlEncodingName = CharsetMapping .getMysqlEncodingForJavaEncoding(charsetResults .toUpperCase(Locale.ENGLISH), this); } // // 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, null, false); if (!this.usingCachedConfig) { this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, mysqlEncodingName); } } else { if (!this.usingCachedConfig) { this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, onServer); } } } if (getConnectionCollation() != null) { StringBuffer setBuf = new StringBuffer( "SET collation_connection = ".length() + getConnectionCollation().length()); setBuf.append("SET collation_connection = ").append( getConnectionCollation()); execSQL(null, setBuf.toString(), -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.database, null, false); } } else { // Use what the server has specified realJavaEncoding = getEncoding(); // so we don't get // swapped out in the finally // block.... } } finally { // Failsafe, make sure that the driver's notion of character // encoding matches what the user has specified. // setEncoding(realJavaEncoding); } return characterSetAlreadyConfigured; } /** * Configures the client's timezone if required. * * @throws SQLException * if the timezone the server is configured to use can't be * mapped to a Java timezone. */ private void configureTimezone() throws SQLException { String configuredTimeZoneOnServer = (String) this.serverVariables .get("timezone"); if (configuredTimeZoneOnServer == null) { configuredTimeZoneOnServer = (String) this.serverVariables .get("time_zone"); if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) { configuredTimeZoneOnServer = (String) this.serverVariables .get("system_time_zone"); } } String canoncicalTimezone = getServerTimezone(); if ((getUseTimezone() || !getUseLegacyDatetimeCode()) && configuredTimeZoneOnServer != null) { // user can override this with driver properties, so don't detect if that's the case if (canoncicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canoncicalTimezone)) { try { canoncicalTimezone = TimeUtil .getCanoncialTimezone(configuredTimeZoneOnServer); if (canoncicalTimezone == null) { throw SQLError.createSQLException("Can't map timezone '" + configuredTimeZoneOnServer + "' to " + " canonical timezone.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } catch (IllegalArgumentException iae) { throw SQLError.createSQLException(iae.getMessage(), SQLError.SQL_STATE_GENERAL_ERROR); } } } else { canoncicalTimezone = getServerTimezone(); } if (canoncicalTimezone != null && canoncicalTimezone.length() > 0) { this.serverTimezoneTZ = TimeZone.getTimeZone(canoncicalTimezone); // // The Calendar class has the behavior of mapping // unknown timezones to 'GMT' instead of throwing an // exception, so we must check for this... // if (!canoncicalTimezone.equalsIgnoreCase("GMT") && this.serverTimezoneTZ.getID().equals("GMT")) { throw SQLError.createSQLException("No timezone mapping entry for '" + canoncicalTimezone + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } if ("GMT".equalsIgnoreCase(this.serverTimezoneTZ.getID())) { this.isServerTzUTC = true; } else { this.isServerTzUTC = false; } } } private void createInitialHistogram(long[] breakpoints, long lowerBound, long upperBound) { double bucketSize = (((double) upperBound - (double) lowerBound) / HISTOGRAM_BUCKETS) * 1.25; if (bucketSize < 1) { bucketSize = 1; } for (int i = 0; i < HISTOGRAM_BUCKETS; i++) { breakpoints[i] = lowerBound; lowerBound += bucketSize; } } /** * Creates an IO channel to the server * * @param isForReconnect * is this request for a re-connect * @return a new MysqlIO instance connected to a server * @throws SQLException * if a database access error occurs * @throws CommunicationsException * DOCUMENT ME! */ protected void createNewIO(boolean isForReconnect) throws SQLException { // Synchronization Not needed for *new* connections, but defintely for // connections going through fail-over, since we might get the // new connection up and running *enough* to start sending // cached or still-open server-side prepared statements over // to the backend before we get a chance to re-prepare them... synchronized (this.mutex) { Properties mergedProps = exposeAsProperties(this.props); long queriesIssuedFailedOverCopy = this.queriesIssuedFailedOver; this.queriesIssuedFailedOver = 0; try { if (!getHighAvailability() && !this.failedOver) { boolean connectionGood = false; Exception connectionNotEstablishedBecause = null; int hostIndex = 0; // // TODO: Eventually, when there's enough metadata // on the server to support it, we should come up // with a smarter way to pick what server to connect // to...perhaps even making it 'pluggable' // if (getRoundRobinLoadBalance()) { hostIndex = getNextRoundRobinHostIndex(getURL(), this.hostList); } for (; hostIndex < this.hostListSize; hostIndex++) { if (hostIndex == 0) { this.hasTriedMasterFlag = true; } try { String newHostPortPair = (String) this.hostList .get(hostIndex); int newPort = 3306; String[] hostPortPair = NonRegisteringDriver .parseHostPortPair(newHostPortPair); String newHost = hostPortPair[NonRegisteringDriver.HOST_NAME_INDEX]; if (newHost == null || StringUtils.isEmptyOrWhitespaceOnly(newHost)) { newHost = "localhost"; } if (hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] != null) { try { newPort = Integer .parseInt(hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX]); } catch (NumberFormatException nfe) { throw SQLError.createSQLException( "Illegal connection port value '" + hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] + "'", SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); } } this.io = new MysqlIO(newHost, newPort, mergedProps, getSocketFactoryClassName(), this, getSocketTimeout(), this.largeRowSizeThreshold.getValueAsInt()); this.io.doHandshake(this.user, this.password, this.database); this.connectionId = this.io.getThreadId(); this.isClosed = false; // save state from old connection boolean oldAutoCommit = getAutoCommit(); int oldIsolationLevel = this.isolationLevel; boolean oldReadOnly = isReadOnly(); String oldCatalog = getCatalog(); // Server properties might be different // from previous connection, so initialize // again... initializePropsFromServer(); if (isForReconnect) { // Restore state from old connection setAutoCommit(oldAutoCommit); if (this.hasIsolationLevels) { setTransactionIsolation(oldIsolationLevel); } setCatalog(oldCatalog); } if (hostIndex != 0) { setFailedOverState(); queriesIssuedFailedOverCopy = 0; } else { this.failedOver = false; queriesIssuedFailedOverCopy = 0; if (this.hostListSize > 1) { setReadOnlyInternal(false); } else { setReadOnlyInternal(oldReadOnly); } } connectionGood = true; break; // low-level connection succeeded } catch (Exception EEE) { if (this.io != null) { this.io.forceClose(); } connectionNotEstablishedBecause = EEE; connectionGood = false; if (EEE instanceof SQLException) { SQLException sqlEx = (SQLException)EEE; String sqlState = sqlEx.getSQLState(); // If this isn't a communications failure, it will probably never succeed, so // give up right here and now .... if ((sqlState == null) || !sqlState .equals(SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE)) { throw sqlEx; } } // Check next host, it might be up... if (getRoundRobinLoadBalance()) { hostIndex = getNextRoundRobinHostIndex(getURL(), this.hostList) - 1 /* incremented by for loop next time around */; } else if ((this.hostListSize - 1) == hostIndex) { throw SQLError.createCommunicationsException(this, (this.io != null) ? this.io .getLastPacketSentTimeMs() : 0, (this.io != null) ? this.io .getLastPacketReceivedTimeMs() : 0, EEE); } } } if (!connectionGood) { // We've really failed! SQLException chainedEx = SQLError.createSQLException( Messages.getString("Connection.UnableToConnect"), SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); chainedEx.initCause(connectionNotEstablishedBecause); throw chainedEx; } } else { double timeout = getInitialTimeout(); boolean connectionGood = false; Exception connectionException = null; int hostIndex = 0; if (getRoundRobinLoadBalance()) { hostIndex = getNextRoundRobinHostIndex(getURL(), this.hostList); } for (; (hostIndex < this.hostListSize) && !connectionGood; hostIndex++) { if (hostIndex == 0) { this.hasTriedMasterFlag = true; } if (this.preferSlaveDuringFailover && hostIndex == 0) { hostIndex++; } for (int attemptCount = 0; (attemptCount < getMaxReconnects()) && !connectionGood; attemptCount++) { try { if (this.io != null) { this.io.forceClose(); } String newHostPortPair = (String) this.hostList .get(hostIndex); int newPort = 3306; String[] hostPortPair = NonRegisteringDriver .parseHostPortPair(newHostPortPair); String newHost = hostPortPair[NonRegisteringDriver.HOST_NAME_INDEX]; if (newHost == null || StringUtils.isEmptyOrWhitespaceOnly(newHost)) { newHost = "localhost"; } if (hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] != null) { try { newPort = Integer .parseInt(hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX]); } catch (NumberFormatException nfe) { throw SQLError.createSQLException( "Illegal connection port value '" + hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] + "'", SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); } } this.io = new MysqlIO(newHost, newPort, mergedProps, getSocketFactoryClassName(), this, ge
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -