src/org/objectweb/cjdbc/controller/connection/RandomWaitPoolConnectionManager.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.controller.connection; 00026 00027 import java.io.Serializable; 00028 import java.sql.Connection; 00029 import java.util.EmptyStackException; 00030 00031 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException; 00032 import org.objectweb.cjdbc.common.i18n.Translate; 00033 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 00034 00045 public class RandomWaitPoolConnectionManager 00046 extends 00047 AbstractPoolConnectionManager implements Serializable 00048 { 00050 private int timeout; 00051 00068 public RandomWaitPoolConnectionManager(String backendUrl, String backendName, 00069 String login, String password, String driverPath, String driverClassName, 00070 int poolSize, int timeout) 00071 { 00072 super(backendUrl, backendName, login, password, driverPath, 00073 driverClassName, poolSize); 00074 this.timeout = timeout * 1000; 00075 } 00076 00080 protected Object clone() throws CloneNotSupportedException 00081 { 00082 return new RandomWaitPoolConnectionManager(backendUrl, backendName, rLogin, 00083 rPassword, driverPath, driverClassName, poolSize,timeout); 00084 } 00085 00091 public int getTimeout() 00092 { 00093 return timeout; 00094 } 00095 00107 public Connection getConnection() throws UnreachableBackendException 00108 { 00109 if (!initialized) 00110 { 00111 logger 00112 .error("Requesting a connection from a non-initialized connection manager"); 00113 return null; 00114 } 00115 00116 long lTimeout = timeout; 00117 synchronized (freeConnections) 00118 { 00119 // We have to do a while loop() because there is a potential race here. 00120 // When freeConnections is notified in releaseConnection, a new thread 00121 // can 00122 // take the lock on freeConnections before we wake up/reacquire the lock 00123 // on freeConnections. Therefore, we could wake up and have no connection 00124 // to take! We ensure that everything is correct with a while statement 00125 // and recomputing the timeout between 2 wakeup. 00126 while (freeConnections.isEmpty()) 00127 { 00128 // Wait 00129 try 00130 { 00131 if (lTimeout > 0) 00132 { 00133 long start = System.currentTimeMillis(); 00134 // Convert seconds to milliseconds for wait call 00135 freeConnections.wait(timeout); 00136 long end = System.currentTimeMillis(); 00137 lTimeout -= end - start; 00138 if (lTimeout <= 0) 00139 { 00140 if (activeConnections.size() == 0) 00141 { // No connection active and backend unreachable, the backend 00142 // is probably dead 00143 logger.error("Backend " + backendName 00144 + " is no more accessible."); 00145 throw new UnreachableBackendException(); 00146 } 00147 if (logger.isWarnEnabled()) 00148 logger.warn("Timeout expired for connection on backend '" 00149 + backendName 00150 + "', consider increasing pool size (current size is " 00151 + poolSize + ") or timeout (current timeout is " 00152 + (timeout / 1000) + " seconds)"); 00153 return null; 00154 } 00155 } 00156 else 00157 freeConnections.wait(); 00158 } 00159 catch (InterruptedException e) 00160 { 00161 logger 00162 .error("Wait on freeConnections interrupted in RandomWaitPoolConnectionManager: " 00163 + e); 00164 return null; 00165 } 00166 } 00167 // Get the connection 00168 try 00169 { 00170 Connection c = (Connection) freeConnections.pop(); 00171 activeConnections.add(c); 00172 return c; 00173 } 00174 catch (EmptyStackException e) 00175 { 00176 int missing = poolSize 00177 - (activeConnections.size() + freeConnections.size()); 00178 if (missing > 0) 00179 { // Re-allocate missing connections 00180 logger.info("Trying to reallocate " + missing 00181 + " missing connections."); 00182 Connection connectionToBeReturned = null; 00183 while (missing > 0) 00184 { 00185 Connection c = getConnectionFromDriver(); 00186 if (c == null) 00187 { 00188 if (missing == poolSize) 00189 { 00190 String msg = Translate.get("loadbalancer.backend.unreacheable", 00191 backendName); 00192 logger.error(msg); 00193 throw new UnreachableBackendException(msg); 00194 } 00195 logger.warn("Unable to re-allocate " + missing 00196 + " missing connections."); 00197 break; 00198 } 00199 else 00200 { 00201 if (connectionToBeReturned == null) 00202 connectionToBeReturned = c; 00203 else 00204 freeConnections.add(c); 00205 } 00206 missing--; 00207 } 00208 return connectionToBeReturned; 00209 } 00210 if (logger.isErrorEnabled()) 00211 logger.error("Failed to get a connection on backend '" + backendName 00212 + "' whereas an idle connection was expected"); 00213 return null; 00214 } 00215 } 00216 } 00217 00221 public void releaseConnection(Connection c) 00222 { 00223 if (!initialized) 00224 return; // We probably have been disabled 00225 00226 synchronized (freeConnections) 00227 { 00228 if (activeConnections.remove(c)) 00229 { 00230 freeConnections.push(c); 00231 freeConnections.notify(); 00232 } 00233 else 00234 logger.error("Failed to release connection " + c 00235 + " (not found in active pool)"); 00236 } 00237 } 00238 00242 public void deleteConnection(Connection c) 00243 { 00244 if (!initialized) 00245 return; // We probably have been disabled 00246 00247 synchronized (freeConnections) 00248 { 00249 if (activeConnections.remove(c)) 00250 { 00251 Connection newConnection = getConnectionFromDriver(); 00252 if (newConnection == null) 00253 { 00254 if (logger.isDebugEnabled()) 00255 logger.error("Bad connection " + c 00256 + " has been removed but cannot be replaced."); 00257 } 00258 else 00259 { 00260 freeConnections.push(newConnection); 00261 freeConnections.notify(); 00262 if (logger.isDebugEnabled()) 00263 logger.debug("Bad connection " + c 00264 + " has been replaced by a new connection."); 00265 } 00266 } 00267 else 00268 logger.error("Failed to release connection " + c 00269 + " (not found in active pool)"); 00270 } 00271 } 00272 00276 public String getXmlImpl() 00277 { 00278 StringBuffer info = new StringBuffer(); 00279 info.append("<" + DatabasesXmlTags.ELT_RandomWaitPoolConnectionManager 00280 + " " + DatabasesXmlTags.ATT_poolSize + "=\"" + poolSize + "\" " 00281 + DatabasesXmlTags.ATT_timeout + "=\"" + timeout / 1000 + "\"/>"); 00282 return info.toString(); 00283 } 00284 00285 }

CJDBCversion1.0.4に対してTue Oct 12 15:16:01 2004に生成されました。 doxygen 1.3.8