1 24 25 package org.continuent.sequoia.controller.loadbalancer.tasks; 26 27 import java.sql.Connection ; 28 import java.sql.SQLException ; 29 30 import org.continuent.sequoia.common.exceptions.NoTransactionStartWhenDisablingException; 31 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 32 import org.continuent.sequoia.common.i18n.Translate; 33 import org.continuent.sequoia.common.log.Trace; 34 import org.continuent.sequoia.controller.backend.DatabaseBackend; 35 import org.continuent.sequoia.controller.backend.result.ControllerResultSet; 36 import org.continuent.sequoia.controller.cache.metadata.MetadataCache; 37 import org.continuent.sequoia.controller.connection.AbstractConnectionManager; 38 import org.continuent.sequoia.controller.connection.PooledConnection; 39 import org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer; 40 import org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread; 41 import org.continuent.sequoia.controller.requests.AbstractRequest; 42 import org.continuent.sequoia.controller.requests.StoredProcedure; 43 44 51 public class CallableStatementExecuteQueryTask extends AbstractTask 52 { 53 private StoredProcedure proc; 54 private ControllerResultSet result = null; 55 private MetadataCache metadataCache; 56 57 static Trace endUserLogger = Trace 58 .getLogger("org.continuent.sequoia.enduser"); 59 60 68 public CallableStatementExecuteQueryTask(int nbToComplete, int totalNb, 69 StoredProcedure proc, MetadataCache metadataCache) 70 { 71 super(nbToComplete, totalNb, proc.isPersistentConnection(), proc 72 .getPersistentConnectionId()); 73 this.proc = proc; 74 this.metadataCache = metadataCache; 75 } 76 77 84 public void executeTask(BackendWorkerThread backendThread) 85 throws SQLException 86 { 87 DatabaseBackend backend = backendThread.getBackend(); 88 89 try 90 { 91 AbstractConnectionManager cm = backend.getConnectionManager(proc 92 .getLogin()); 93 if (cm == null) 94 { 95 SQLException se = new SQLException ( 96 "No Connection Manager for Virtual Login:" + proc.getLogin()); 97 try 98 { 99 notifyFailure(backendThread, -1, se); 100 } 101 catch (SQLException ignore) 102 { 103 104 } 105 throw se; 106 } 107 108 Trace logger = backendThread.getLogger(); 109 if (proc.isAutoCommit()) 110 executeInAutoCommit(backendThread, backend, cm, logger); 111 else 112 executeInTransaction(backendThread, backend, cm, logger); 113 114 if (result != null) 115 notifySuccess(backendThread); 116 } 117 finally 118 { 119 backend.getTaskQueues().completeStoredProcedureExecution(this); 120 } 121 } 122 123 private void executeInAutoCommit(BackendWorkerThread backendThread, 124 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 125 throws SQLException 126 { 127 if (!backend.canAcceptTasks(proc)) 128 { 129 notifyCompletion(backendThread); 134 return; 135 } 136 137 PooledConnection c = null; 139 try 140 { 141 c = cm.retrieveConnectionInAutoCommit(proc); 142 } 143 catch (UnreachableBackendException e1) 144 { 145 SQLException se = new SQLException ("Backend " + backend.getName() 146 + " is no more reachable."); 147 try 148 { 149 notifyFailure(backendThread, -1, se); 150 } 151 catch (SQLException ignore) 152 { 153 } 154 backendThread.getLoadBalancer().disableBackend(backend, true); 157 String msg = Translate.get("loadbalancer.backend.disabling.unreachable", 158 backend.getName()); 159 logger.error(msg); 160 endUserLogger.error(msg); 161 throw se; 162 } 163 164 if (c == null) 166 { 167 SQLException se = new SQLException ("No more connections"); 168 try 169 { if (!notifyFailure(backendThread, proc.getTimeout() * 1000L, se)) 171 return; 172 } 173 catch (SQLException ignore) 174 { 175 } 176 backendThread.getLoadBalancer().disableBackend(backend, true); 179 String msg = "Stored procedure '" 180 + proc.getSqlShortForm(backend.getSqlShortFormLength()) 181 + "' failed on backend " + backend.getName() + " but " + getSuccess() 182 + " succeeded (" + se + ")"; 183 logger.error(msg); 184 endUserLogger.error(Translate.get("loadbalancer.backend.disabling", 185 backend.getName())); 186 throw new SQLException (msg); 187 } 188 189 try 191 { 192 result = AbstractLoadBalancer 193 .executeCallableStatementExecuteQueryOnBackend(proc, backend, 194 backendThread, c.getConnection(), metadataCache); 195 196 backend.setSchemaIsDirtyIfNeeded(proc); 197 } 198 catch (Exception e) 199 { 200 try 201 { if (!notifyFailure(backendThread, proc.getTimeout() * 1000L, e)) 203 { 204 result = null; 205 return; 206 } 207 } 208 catch (SQLException ignore) 209 { 210 } 211 backendThread.getLoadBalancer().disableBackend(backend, true); 214 String msg = "Stored procedure '" 215 + proc.getSqlShortForm(backend.getSqlShortFormLength()) 216 + "' failed on backend " + backend.getName() + " but " + getSuccess() 217 + " succeeded (" + e + ")"; 218 logger.error(msg); 219 endUserLogger.error(Translate.get("loadbalancer.backend.disabling", 220 backend.getName())); 221 throw new SQLException (msg); 222 } 223 finally 224 { 225 cm.releaseConnectionInAutoCommit(proc, c); 226 } 227 } 228 229 private void executeInTransaction(BackendWorkerThread backendThread, 230 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 231 throws SQLException 232 { 233 Connection c; 235 long tid = proc.getTransactionId(); 236 237 try 238 { 239 c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(proc, cm); 240 } 241 catch (UnreachableBackendException ube) 242 { 243 SQLException se = new SQLException ("Backend " + backend.getName() 244 + " is no more reachable."); 245 try 246 { 247 notifyFailure(backendThread, -1, se); 248 } 249 catch (SQLException ignore) 250 { 251 } 252 backendThread.getLoadBalancer().disableBackend(backend, true); 255 String msg = Translate.get("loadbalancer.backend.disabling.unreachable", 256 backend.getName()); 257 logger.error(msg); 258 endUserLogger.error(msg); 259 throw se; 260 } 261 catch (NoTransactionStartWhenDisablingException e) 262 { 263 notifyCompletion(backendThread); 268 return; 269 } 270 catch (SQLException e1) 271 { 272 SQLException se = new SQLException ( 273 "Unable to get connection for transaction " + tid); 274 try 275 { if (!notifyFailure(backendThread, proc.getTimeout() * 1000L, se)) 277 return; 278 } 279 catch (SQLException ignore) 280 { 281 } 282 backendThread.getLoadBalancer().disableBackend(backend, true); 285 String msg = "Request '" 286 + proc.getSqlShortForm(backend.getSqlShortFormLength()) 287 + "' failed on backend " + backend.getName() + " but " + getSuccess() 288 + " succeeded (" + se + ")"; 289 logger.error(msg); 290 endUserLogger.error(Translate.get("loadbalancer.backend.disabling", 291 backend.getName())); 292 throw new SQLException (msg); 293 } 294 295 if (c == null) 297 { SQLException se = new SQLException ( 299 "Unable to retrieve connection for transaction " + tid); 300 try 301 { if (!notifyFailure(backendThread, proc.getTimeout() * 1000L, se)) 303 return; 304 } 305 catch (SQLException ignore) 306 { 307 } 308 backendThread.getLoadBalancer().disableBackend(backend, true); 311 String msg = "Request '" 312 + proc.getSqlShortForm(backend.getSqlShortFormLength()) 313 + "' failed on backend " + backend.getName() + " but " + getSuccess() 314 + " succeeded (" + se + ")"; 315 logger.error(msg); 316 endUserLogger.error(Translate.get("loadbalancer.backend.disabling", 317 backend.getName())); 318 throw new SQLException (msg); 319 } 320 321 try 323 { 324 result = AbstractLoadBalancer 325 .executeCallableStatementExecuteQueryOnBackend(proc, backend, 326 backendThread, c, metadataCache); 327 328 backend.setSchemaIsDirtyIfNeeded(proc); 329 } 330 catch (Exception e) 331 { 332 try 333 { if (!notifyFailure(backendThread, proc.getTimeout() * 1000L, e)) 335 { 336 result = null; 337 return; 338 } 339 } 340 catch (SQLException ignore) 341 { 342 } 343 backendThread.getLoadBalancer().disableBackend(backend, true); 346 String msg = "Stored procedure '" 347 + proc.getSqlShortForm(backend.getSqlShortFormLength()) 348 + "' failed on backend " + backend.getName() + " but " + getSuccess() 349 + " succeeded (" + e + ")"; 350 logger.error(msg); 351 endUserLogger.error(Translate.get("loadbalancer.backend.disabling", 352 backend.getName())); 353 throw new SQLException (msg); 354 } 355 } 356 357 360 public AbstractRequest getRequest() 361 { 362 return proc; 363 } 364 365 370 public ControllerResultSet getResult() 371 { 372 return result; 373 } 374 375 378 public long getTransactionId() 379 { 380 return proc.getTransactionId(); 381 } 382 383 386 public boolean isAutoCommit() 387 { 388 return proc.isAutoCommit(); 389 } 390 391 394 public boolean equals(Object other) 395 { 396 if ((other == null) 397 || !(other instanceof CallableStatementExecuteQueryTask)) 398 return false; 399 400 CallableStatementExecuteQueryTask cseqt = (CallableStatementExecuteQueryTask) other; 401 if (proc == null) 402 return cseqt.getRequest() == null; 403 return proc.equals(cseqt.getRequest()); 404 } 405 406 409 public int hashCode() 410 { 411 return (int) proc.getId(); 412 } 413 414 417 public String toString() 418 { 419 if (proc.isAutoCommit()) 420 return "Autocommit CallableStatementExecuteQueryTask " 421 + proc.getTransactionId() + " (" + proc.getUniqueKey() + ")"; 422 else 423 return "CallableStatementExecuteQueryTask for transaction " 424 + proc.getTransactionId() + " (" + proc.getUniqueKey() + ")"; 425 } 426 427 } | Popular Tags |