List:Commits« Previous MessageNext Message »
From:mmatthews Date:October 4 2007 9:31pm
Subject:Connector/J commit: r6614 - in branches/branch_5_0/connector-j: . src/com/mysql/jdbc
View as plain text  
Modified:
   branches/branch_5_0/connector-j/CHANGES
   branches/branch_5_0/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java
Log:
Fixed BUG#31053 - Connections established using URLs of the form
      "jdbc:mysql:loadbalance://" weren't doing failover if they tried to 
      connect to a MySQL server that was down. The driver now attempts
      connections to the next "best" (depending on the load balance strategy
      in use) server, and continues to attempt connecting to the next "best"
      server every 250 milliseconds until one is found that is up and running 
      or 5 minutes has passed.
      
      If the driver gives up, it will throw the last-received SQLException.

Modified: branches/branch_5_0/connector-j/CHANGES
===================================================================
--- branches/branch_5_0/connector-j/CHANGES	2007-10-04 16:56:05 UTC (rev 6613)
+++ branches/branch_5_0/connector-j/CHANGES	2007-10-04 19:31:52 UTC (rev 6614)
@@ -81,6 +81,16 @@
       This fix also ensures that the precision of UNSIGNED MEDIUMINT
       and UNSIGNED BIGINT is reported correctly via DBMD.getColumns().
 
+    - Fixed BUG#31053 - Connections established using URLs of the form
+      "jdbc:mysql:loadbalance://" weren't doing failover if they tried to 
+      connect to a MySQL server that was down. The driver now attempts
+      connections to the next "best" (depending on the load balance strategy
+      in use) server, and continues to attempt connecting to the next "best"
+      server every 250 milliseconds until one is found that is up and running 
+      or 5 minutes has passed.
+      
+      If the driver gives up, it will throw the last-received SQLException.
+      
 07-19-07 - Version 5.0.7
 
     - Setting the configuration parameter "useCursorFetch" to "true" for 

Modified:
branches/branch_5_0/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java
===================================================================
---
branches/branch_5_0/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java	2007-10-04
16:56:05 UTC (rev 6613)
+++
branches/branch_5_0/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java	2007-10-04
19:31:52 UTC (rev 6614)
@@ -80,30 +80,73 @@
 
 			int bestHostIndex = 0;
 
-			for (int i = 0; i < responseTimes.length; i++) {
-				long candidateResponseTime = responseTimes[i];
-
-				if (candidateResponseTime < minResponseTime) {
-					if (candidateResponseTime == 0) {
+			long[] localResponseTimes = new long[responseTimes.length];
+			
+			synchronized (responseTimes) {
+				System.arraycopy(responseTimes, 0, localResponseTimes, 0, responseTimes.length);
+			}
+			
+			SQLException ex = null;
+			
+			for (int attempts = 0; attempts < 1200 /* 5 minutes */; attempts++) {
+				for (int i = 0; i < localResponseTimes.length; i++) {
+					long candidateResponseTime = localResponseTimes[i];
+	
+					if (candidateResponseTime < minResponseTime) {
+						if (candidateResponseTime == 0) {
+							bestHostIndex = i;
+	
+							break;
+						}
+	
 						bestHostIndex = i;
-
-						break;
+						minResponseTime = candidateResponseTime;
 					}
-
-					bestHostIndex = i;
-					minResponseTime = candidateResponseTime;
 				}
+	
+				if (bestHostIndex == localResponseTimes.length - 1) {
+					// try again, assuming that the previous list was mostly
+					// correct as far as distribution of response times went
+					
+					synchronized (responseTimes) {
+						System.arraycopy(responseTimes, 0, localResponseTimes, 0, responseTimes.length);
+					}
+					
+					continue;
+				}
+				String bestHost = (String) hostList.get(bestHostIndex);
+	
+				Connection conn = (Connection) liveConnections.get(bestHost);
+	
+				if (conn == null) {
+					try {
+						conn = createConnectionForHost(bestHost);
+					} catch (SQLException sqlEx) {
+						ex = sqlEx;
+						
+						if (sqlEx instanceof CommunicationsException ||
"08S01".equals(sqlEx.getSQLState())) {
+							localResponseTimes[bestHostIndex] = Long.MAX_VALUE;
+							
+							try {
+								Thread.sleep(250);
+							} catch (InterruptedException e) {
+							}
+							
+							continue;
+						} else {
+							throw sqlEx;
+						}
+					}
+				}
+	
+				return conn;
 			}
-
-			String bestHost = (String) hostList.get(bestHostIndex);
-
-			Connection conn = (Connection) liveConnections.get(bestHost);
-
-			if (conn == null) {
-				conn = createConnectionForHost(bestHost);
+			
+			if (ex != null) {
+				throw ex;
 			}
-
-			return conn;
+			
+			return null; // we won't get here, compiler can't tell
 		}
 	}
 
@@ -146,14 +189,41 @@
 
 			String hostPortSpec = (String) hostList.get(random);
 
-			Connection conn = (Connection) liveConnections.get(hostPortSpec);
-
-			if (conn == null) {
-				conn = createConnectionForHost(hostPortSpec);
+			SQLException ex = null;
+			
+			for (int attempts = 0; attempts < 1200 /* 5 minutes */; attempts++) {
+				Connection conn = (Connection) liveConnections.get(hostPortSpec);
+				
+				if (conn == null) {
+					try {
+						conn = createConnectionForHost(hostPortSpec);
+					} catch (SQLException sqlEx) {
+						ex = sqlEx;
+						
+						if (sqlEx instanceof CommunicationsException ||
"08S01".equals(sqlEx.getSQLState())) {
+							
+							try {
+								Thread.sleep(250);
+							} catch (InterruptedException e) {
+							}
+							
+							continue;
+						} else {
+							throw sqlEx;
+						}
+					}
+				}
+	
+				return conn;
 			}
+			
+			if (ex != null) {
+				throw ex;
+			}
+			
+			return null; // we won't get here, compiler can't tell
+		}
 
-			return conn;
-		}
 	}
 
 	private Connection currentConn;
@@ -370,8 +440,10 @@
 						.get(this.connectionsToHostsMap.get(this.currentConn)))
 						.intValue();
 
-				this.responseTimes[hostIndex] = getLocalTimeBestResolution()
-						- this.transactionStartTime;
+				synchronized (this.responseTimes) {
+					this.responseTimes[hostIndex] = getLocalTimeBestResolution()
+							- this.transactionStartTime;
+				}
 
 				pickNewConnection();
 			}

Thread
Connector/J commit: r6614 - in branches/branch_5_0/connector-j: . src/com/mysql/jdbcmmatthews4 Oct