1 35 36 package org.continuent.sequoia.controller.loadbalancer.tasks; 37 38 import java.sql.Connection ; 39 import java.sql.SQLException ; 40 41 import org.continuent.sequoia.common.exceptions.NoTransactionStartWhenDisablingException; 42 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 43 import org.continuent.sequoia.common.i18n.Translate; 44 import org.continuent.sequoia.common.log.Trace; 45 import org.continuent.sequoia.controller.backend.DatabaseBackend; 46 import org.continuent.sequoia.controller.backend.result.ControllerResultSet; 47 import org.continuent.sequoia.controller.cache.metadata.MetadataCache; 48 import org.continuent.sequoia.controller.connection.AbstractConnectionManager; 49 import org.continuent.sequoia.controller.connection.PooledConnection; 50 import org.continuent.sequoia.controller.core.ControllerConstants; 51 import org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer; 52 import org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread; 53 import org.continuent.sequoia.controller.requests.AbstractRequest; 54 import org.continuent.sequoia.controller.requests.SelectRequest; 55 56 64 public class StatementExecuteQueryTask extends AbstractTask 65 { 66 private SelectRequest request; 67 private MetadataCache metadataCache; 68 private ControllerResultSet result = null; 69 70 static Trace endUserLogger = Trace 71 .getLogger("org.continuent.sequoia.enduser"); 72 73 81 public StatementExecuteQueryTask(int nbToComplete, int totalNb, 82 SelectRequest request, MetadataCache metadataCache) 83 { 84 super(nbToComplete, totalNb, request.isPersistentConnection(), request 85 .getPersistentConnectionId()); 86 this.request = request; 87 this.metadataCache = metadataCache; 88 } 89 90 96 public void executeTask(BackendWorkerThread backendThread) 97 throws SQLException 98 { 99 DatabaseBackend backend = backendThread.getBackend(); 100 101 try 102 { 103 AbstractConnectionManager cm = backend.getConnectionManager(request 104 .getLogin()); 105 if (cm == null) 106 { 107 SQLException se = new SQLException ( 108 "No Connection Manager for Virtual Login:" + request.getLogin()); 109 try 110 { 111 notifyFailure(backendThread, -1, se); 112 } 113 catch (SQLException ignore) 114 { 115 116 } 117 throw se; 118 } 119 120 Trace logger = backendThread.getLogger(); 121 if (request.isAutoCommit()) 122 executeInAutoCommit(backendThread, backend, cm, logger); 123 else 124 executeInTransaction(backendThread, backend, cm, logger); 125 126 if (result != null) 127 notifySuccess(backendThread); 128 } 129 finally 130 { 131 backend.getTaskQueues().completeWriteRequestExecution(this); 132 } 133 } 134 135 private void executeInAutoCommit(BackendWorkerThread backendThread, 136 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 137 throws SQLException 138 { 139 if (!backend.canAcceptTasks(request)) 140 { 141 notifyCompletion(backendThread); 145 return; 146 } 147 148 PooledConnection c = null; 150 try 151 { 152 c = cm.retrieveConnectionInAutoCommit(request); 153 } 154 catch (UnreachableBackendException e1) 155 { 156 SQLException se = new SQLException ("Backend " + backend.getName() 157 + " is no more reachable."); 158 try 159 { 160 notifyFailure(backendThread, -1, se); 161 } 162 catch (SQLException ignore) 163 { 164 } 165 backendThread.getLoadBalancer().disableBackend(backend, true); 168 String msg = Translate.get( 169 "loadbalancer.backend.disabling.unreachable", backend.getName()); 170 logger.error(msg); 171 endUserLogger.error(msg); 172 throw se; 173 } 174 175 if (c == null) 177 { 178 SQLException se = new SQLException ("No more connections"); 179 try 180 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 182 return; 183 } 184 catch (SQLException ignore) 185 { 186 } 187 backendThread.getLoadBalancer().disableBackend(backend, true); 190 endUserLogger.error(Translate.get( 191 "loadbalancer.backend.disabling", backend.getName())); 192 throw new SQLException ("Request '" 193 + request.getSqlShortForm(ControllerConstants.SQL_SHORT_FORM_LENGTH) 194 + "' failed on backend " + backend.getName() + " (" + se + ")"); 195 } 196 197 try 199 { 200 result = AbstractLoadBalancer.executeStatementExecuteQueryOnBackend( 201 request, backend, backendThread, c.getConnection(), metadataCache); 202 } 203 catch (Throwable e) 204 { 205 try 206 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, e)) 208 { 209 result = null; 210 return; 211 } 212 } 213 catch (SQLException ignore) 214 { 215 } 216 throw new SQLException ("Request '" 217 + request.getSqlShortForm(ControllerConstants.SQL_SHORT_FORM_LENGTH) 218 + "' failed on backend " + backend.getName() + " (" + e + ")"); 219 } 220 finally 221 { 222 cm.releaseConnectionInAutoCommit(request, c); 223 } 224 } 225 226 private void executeInTransaction(BackendWorkerThread backendThread, 227 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 228 throws SQLException 229 { 230 Connection c; 231 long tid = request.getTransactionId(); 232 233 try 234 { 235 c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(request, cm); 236 } 237 catch (UnreachableBackendException ube) 238 { 239 SQLException se = new SQLException ("Backend " + backend.getName() 240 + " is no more reachable."); 241 try 242 { 243 notifyFailure(backendThread, -1, se); 244 } 245 catch (SQLException ignore) 246 { 247 } 248 backendThread.getLoadBalancer().disableBackend(backend, true); 251 String msg = Translate.get( 252 "loadbalancer.backend.disabling.unreachable", backend.getName()); 253 logger.error(msg); 254 endUserLogger.error(msg); 255 throw se; 256 } 257 catch (NoTransactionStartWhenDisablingException e) 258 { 259 notifyCompletion(backendThread); 263 return; 264 } 265 catch (SQLException e1) 266 { 267 SQLException se = new SQLException ( 268 "Unable to get connection for transaction " + tid); 269 try 270 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 272 return; 273 } 274 catch (SQLException ignore) 275 { 276 } 277 backendThread.getLoadBalancer().disableBackend(backend, true); 280 String msg = "Request '" 281 + request.getSqlShortForm(backend.getSqlShortFormLength()) 282 + "' failed on backend " + backend.getName() + " but " + getSuccess() 283 + " succeeded (" + se + ")"; 284 logger.error(msg); 285 endUserLogger.error(Translate.get( 286 "loadbalancer.backend.disabling", backend.getName())); 287 throw new SQLException (msg); 288 } 289 290 if (c == null) 292 { SQLException se = new SQLException ( 294 "Unable to retrieve connection for transaction " + tid); 295 try 296 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 298 return; 299 } 300 catch (SQLException ignore) 301 { 302 } 303 backendThread.getLoadBalancer().disableBackend(backend, true); 306 String msg = "Request '" 307 + request.getSqlShortForm(backend.getSqlShortFormLength()) 308 + "' failed on backend " + backend.getName() + " but " + getSuccess() 309 + " succeeded (" + se + ")"; 310 logger.error(msg); 311 endUserLogger.error(Translate.get( 312 "loadbalancer.backend.disabling", backend.getName())); 313 throw new SQLException (msg); 314 } 315 316 try 318 { 319 result = AbstractLoadBalancer.executeStatementExecuteQueryOnBackend( 320 request, backend, backendThread, c, metadataCache); 321 } 322 catch (Throwable e) 323 { 324 try 325 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, e)) 327 { 328 result = null; 329 return; 330 } 331 } 332 catch (SQLException ignore) 333 { 334 } 335 throw new SQLException ("Request '" 336 + request.getSqlShortForm(ControllerConstants.SQL_SHORT_FORM_LENGTH) 337 + "' failed on backend " + backend.getName() + " (" + e + ")"); 338 } 339 } 340 341 344 public AbstractRequest getRequest() 345 { 346 return request; 347 } 348 349 354 public ControllerResultSet getResult() 355 { 356 return result; 357 } 358 359 362 public long getTransactionId() 363 { 364 return request.getTransactionId(); 365 } 366 367 370 public boolean isAutoCommit() 371 { 372 return request.isAutoCommit(); 373 } 374 375 378 public boolean equals(Object other) 379 { 380 if ((other == null) || !(other instanceof StatementExecuteQueryTask)) 381 return false; 382 383 StatementExecuteQueryTask seqt = (StatementExecuteQueryTask) other; 384 return this.request.equals(seqt.getRequest()); 385 } 386 387 390 public int hashCode() 391 { 392 return (int) request.getId(); 393 } 394 395 398 public String toString() 399 { 400 if (request.isAutoCommit()) 401 return "Autocommit StatementExecuteQueryTask (" + request.getUniqueKey() 402 + ")"; 403 else 404 return "StatementExecuteQueryTask from transaction " 405 + request.getTransactionId() + " (" + request.getUniqueKey() + ")"; 406 } 407 } | Popular Tags |