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.ExecuteResult; 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.AbstractWriteRequest; 43 44 52 public class StatementExecuteTask extends AbstractTask 53 { 54 private AbstractWriteRequest request; 55 private ExecuteResult result = null; 56 private MetadataCache metadataCache; 57 58 static Trace endUserLogger = Trace 59 .getLogger("org.continuent.sequoia.enduser"); 60 61 69 public StatementExecuteTask(int nbToComplete, int totalNb, 70 AbstractWriteRequest request, MetadataCache metadataCache) 71 { 72 super(nbToComplete, totalNb, request.isPersistentConnection(), request 73 .getPersistentConnectionId()); 74 this.request = request; 75 this.metadataCache = metadataCache; 76 } 77 78 85 public void executeTask(BackendWorkerThread backendThread) 86 throws SQLException 87 { 88 DatabaseBackend backend = backendThread.getBackend(); 89 90 try 91 { 92 AbstractConnectionManager cm = backend.getConnectionManager(request 93 .getLogin()); 94 if (cm == null) 95 { 96 SQLException se = new SQLException ( 97 "No Connection Manager for Virtual Login:" + request.getLogin()); 98 try 99 { 100 notifyFailure(backendThread, -1, se); 101 } 102 catch (SQLException ignore) 103 { 104 105 } 106 throw se; 107 } 108 109 Trace logger = backendThread.getLogger(); 110 if (request.isAutoCommit()) 111 executeInAutoCommit(backendThread, backend, cm, logger); 112 else 113 executeInTransaction(backendThread, backend, cm, logger); 114 115 if (result != null) 116 notifySuccess(backendThread); 117 } 118 finally 119 { 120 backend.getTaskQueues().completeWriteRequestExecution(this); 121 } 122 } 123 124 private void executeInAutoCommit(BackendWorkerThread backendThread, 125 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 126 throws SQLException 127 { 128 if (!backend.canAcceptTasks(request)) 129 { 130 notifyCompletion(backendThread); 134 return; 135 } 136 137 PooledConnection c = null; 139 try 140 { 141 c = cm.retrieveConnectionInAutoCommit(request); 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( 158 "loadbalancer.backend.disabling.unreachable", 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, request.getTimeout() * 1000L, se)) 171 return; 172 } 173 catch (SQLException ignore) 174 { 175 } 176 backendThread.getLoadBalancer().disableBackend(backend, true); 179 String msg = "Stored procedure '" 180 + request.getSqlShortForm(backend.getSqlShortFormLength()) 181 + "' failed on backend " + backend.getName() + " but " + getSuccess() 182 + " succeeded (" + se + ")"; 183 logger.error(msg); 184 endUserLogger.error(Translate.get( 185 "loadbalancer.backend.disabling", backend.getName())); 186 throw new SQLException (msg); 187 } 188 189 try 191 { 192 result = AbstractLoadBalancer.executeStatementExecuteOnBackend(request, 193 backend, backendThread, c.getConnection(), metadataCache); 194 195 backend.updateDatabaseBackendSchema(request); 196 } 197 catch (Exception e) 198 { 199 try 200 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, e)) 202 { 203 result = null; 204 return; 205 } 206 } 207 catch (SQLException ignore) 208 { 209 } 210 backendThread.getLoadBalancer().disableBackend(backend, true); 213 String msg = "Stored procedure '" 214 + request.getSqlShortForm(backend.getSqlShortFormLength()) 215 + "' failed on backend " + backend.getName() + " but " + getSuccess() 216 + " succeeded (" + e + ")"; 217 logger.error(msg); 218 endUserLogger.error(Translate.get( 219 "loadbalancer.backend.disabling", backend.getName())); 220 throw new SQLException (msg); 221 } 222 finally 223 { 224 cm.releaseConnectionInAutoCommit(request, c); 225 } 226 } 227 228 private void executeInTransaction(BackendWorkerThread backendThread, 229 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 230 throws SQLException 231 { 232 Connection c; 234 long tid = request.getTransactionId(); 235 236 try 237 { 238 c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(request, cm); 239 } 240 catch (UnreachableBackendException ube) 241 { 242 SQLException se = new SQLException ("Backend " + backend.getName() 243 + " is no more reachable."); 244 try 245 { 246 notifyFailure(backendThread, -1, se); 247 } 248 catch (SQLException ignore) 249 { 250 } 251 backendThread.getLoadBalancer().disableBackend(backend, true); 254 String msg = Translate.get( 255 "loadbalancer.backend.disabling.unreachable", backend.getName()); 256 logger.error(msg); 257 endUserLogger.error(msg); 258 throw se; 259 } 260 catch (NoTransactionStartWhenDisablingException e) 261 { 262 notifyCompletion(backendThread); 266 return; 267 } 268 catch (SQLException e1) 269 { 270 SQLException se = new SQLException ( 271 "Unable to get connection for transaction " + tid); 272 try 273 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 275 return; 276 } 277 catch (SQLException ignore) 278 { 279 } 280 backendThread.getLoadBalancer().disableBackend(backend, true); 283 String msg = "Request '" 284 + request.getSqlShortForm(backend.getSqlShortFormLength()) 285 + "' failed on backend " + backend.getName() + " but " + getSuccess() 286 + " succeeded (" + se + ")"; 287 logger.error(msg); 288 endUserLogger.error(Translate.get( 289 "loadbalancer.backend.disabling", backend.getName())); 290 throw new SQLException (msg); 291 } 292 293 if (c == null) 295 { SQLException se = new SQLException ( 297 "Unable to retrieve connection for transaction " + tid); 298 try 299 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 301 return; 302 } 303 catch (SQLException ignore) 304 { 305 } 306 backendThread.getLoadBalancer().disableBackend(backend, true); 309 String msg = "Request '" 310 + request.getSqlShortForm(backend.getSqlShortFormLength()) 311 + "' failed on backend " + backend.getName() + " but " + getSuccess() 312 + " succeeded (" + se + ")"; 313 logger.error(msg); 314 endUserLogger.error(Translate.get( 315 "loadbalancer.backend.disabling", backend.getName())); 316 throw new SQLException (msg); 317 } 318 319 try 321 { 322 result = AbstractLoadBalancer.executeStatementExecuteOnBackend(request, 323 backend, backendThread, c, metadataCache); 324 325 backend.updateDatabaseBackendSchema(request); 326 } 327 catch (Exception e) 328 { 329 try 330 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, e)) 332 { 333 result = null; 334 return; 335 } 336 } 337 catch (SQLException ignore) 338 { 339 } 340 backendThread.getLoadBalancer().disableBackend(backend, true); 343 String msg = "Stored procedure '" 344 + request.getSqlShortForm(backend.getSqlShortFormLength()) 345 + "' failed on backend " + backend.getName() + " but " + getSuccess() 346 + " succeeded (" + e + ")"; 347 logger.error(msg); 348 endUserLogger.error(Translate.get( 349 "loadbalancer.backend.disabling", backend.getName())); 350 throw new SQLException (msg); 351 } 352 } 353 354 357 public AbstractRequest getRequest() 358 { 359 return request; 360 } 361 362 367 public ExecuteResult getResult() 368 { 369 return result; 370 } 371 372 375 public long getTransactionId() 376 { 377 return request.getTransactionId(); 378 } 379 380 383 public boolean isAutoCommit() 384 { 385 return request.isAutoCommit(); 386 } 387 388 391 public boolean equals(Object other) 392 { 393 if ((other == null) || !(other instanceof StatementExecuteTask)) 394 return false; 395 396 StatementExecuteTask sexec = (StatementExecuteTask) other; 397 return this.request.equals(sexec.getRequest()); 398 } 399 400 403 public int hashCode() 404 { 405 return (int) request.getId(); 406 } 407 408 411 public String toString() 412 { 413 if (request.isAutoCommit()) 414 return "Autocommit StatementExecuteTask " + request.getTransactionId() 415 + " (" + request.getUniqueKey() + ")"; 416 else 417 return "StatementExecuteTask for transaction " 418 + request.getTransactionId() + " (" + request.getUniqueKey() + ")"; 419 } 420 } | Popular Tags |