1 23 24 package org.continuent.sequoia.controller.loadbalancer.tasks; 25 26 import java.sql.Connection ; 27 import java.sql.SQLException ; 28 29 import org.continuent.sequoia.common.exceptions.NoTransactionStartWhenDisablingException; 30 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 31 import org.continuent.sequoia.common.i18n.Translate; 32 import org.continuent.sequoia.common.log.Trace; 33 import org.continuent.sequoia.controller.backend.DatabaseBackend; 34 import org.continuent.sequoia.controller.backend.result.GeneratedKeysResult; 35 import org.continuent.sequoia.controller.cache.metadata.MetadataCache; 36 import org.continuent.sequoia.controller.connection.AbstractConnectionManager; 37 import org.continuent.sequoia.controller.connection.PooledConnection; 38 import org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer; 39 import org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread; 40 import org.continuent.sequoia.controller.requests.AbstractRequest; 41 import org.continuent.sequoia.controller.requests.AbstractWriteRequest; 42 43 51 public class StatementExecuteUpdateWithKeysTask extends AbstractTask 52 { 53 private AbstractWriteRequest request; 54 private GeneratedKeysResult result = null; 55 private MetadataCache metadataCache; 56 57 static Trace endUserLogger = Trace 58 .getLogger("org.continuent.sequoia.enduser"); 59 60 68 public StatementExecuteUpdateWithKeysTask(int nbToComplete, int totalNb, 69 AbstractWriteRequest request, MetadataCache metadataCache) 70 { 71 super(nbToComplete, totalNb, request.isPersistentConnection(), request 72 .getPersistentConnectionId()); 73 this.request = request; 74 this.metadataCache = metadataCache; 75 } 76 77 83 public void executeTask(BackendWorkerThread backendThread) 84 throws SQLException 85 { 86 DatabaseBackend backend = backendThread.getBackend(); 87 88 try 89 { 90 if (!backend.getDriverCompliance().supportGetGeneratedKeys()) 91 throw new SQLException (Translate.get( 92 "loadbalancer.backend.autogeneratedkeys.unsupported", backend 93 .getName())); 94 95 AbstractConnectionManager cm = backend.getConnectionManager(request 96 .getLogin()); 97 if (cm == null) 98 { 99 SQLException se = new SQLException ( 100 "No Connection Manager for Virtual Login:" + request.getLogin()); 101 try 102 { 103 notifyFailure(backendThread, -1, se); 104 } 105 catch (SQLException ignore) 106 { 107 108 } 109 throw se; 110 } 111 112 Trace logger = backendThread.getLogger(); 113 if (request.isAutoCommit()) 114 executeInAutoCommit(backendThread, backend, cm, logger); 115 else 116 executeInTransaction(backendThread, backend, cm, logger); 117 118 if (result == null) 119 return; 121 int resultOnFirstBackendToSucceed = notifySuccess(backendThread, result 122 .getUpdateCount()); 123 if (resultOnFirstBackendToSucceed != result.getUpdateCount()) 124 { 125 String msg = "Disabling backend " + backend.getName() 126 + " that reports a different number of updated rows (" 127 + result.getUpdateCount() + ") than first backend to succeed (" 128 + resultOnFirstBackendToSucceed + ") for request " + request; 129 logger.error(msg); 130 backendThread.getLoadBalancer().disableBackend(backend, true); 132 endUserLogger.error(Translate.get( 133 "loadbalancer.backend.disabling", backend.getName())); 134 throw new SQLException (msg); 135 } 136 } 137 finally 138 { 139 backend.getTaskQueues().completeWriteRequestExecution(this); 140 } 141 } 142 143 private void executeInAutoCommit(BackendWorkerThread backendThread, 144 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 145 throws SQLException 146 { 147 if (!backend.canAcceptTasks(request)) 148 { 149 notifyCompletion(backendThread); 153 return; 154 } 155 156 PooledConnection c = null; 158 try 159 { 160 c = cm.retrieveConnectionInAutoCommit(request); 161 } 162 catch (UnreachableBackendException e1) 163 { 164 SQLException se = new SQLException ("Backend " + backend.getName() 165 + " is no more reachable."); 166 try 167 { 168 notifyFailure(backendThread, -1, se); 169 } 170 catch (SQLException ignore) 171 { 172 } 173 backendThread.getLoadBalancer().disableBackend(backend, true); 176 String msg = Translate.get( 177 "loadbalancer.backend.disabling.unreachable", backend.getName()); 178 logger.error(msg); 179 endUserLogger.error(msg); 180 throw se; 181 } 182 183 if (c == null) 185 { 186 SQLException se = new SQLException ("No more connections"); 187 try 188 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 190 return; 191 } 192 catch (SQLException ignore) 193 { 194 } 195 backendThread.getLoadBalancer().disableBackend(backend, true); 198 String msg = "Request '" 199 + request.getSqlShortForm(backend.getSqlShortFormLength()) 200 + "' failed on backend " + backend.getName() + " but " + getSuccess() 201 + " succeeded (" + se + ")"; 202 logger.error(msg); 203 endUserLogger.error(Translate.get( 204 "loadbalancer.backend.disabling", backend.getName())); 205 throw new SQLException (msg); 206 } 207 208 try 210 { 211 result = AbstractLoadBalancer 212 .executeStatementExecuteUpdateWithKeysOnBackend(request, backend, 213 backendThread, c.getConnection(), metadataCache); 214 215 backend.updateDatabaseBackendSchema(request); 216 } 217 catch (Exception e) 218 { 219 try 220 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, e)) 222 { 223 result = null; 224 return; 225 } 226 } 227 catch (SQLException ignore) 228 { 229 } 230 backendThread.getLoadBalancer().disableBackend(backend, true); 233 String msg = "Request '" 234 + request.getSqlShortForm(backend.getSqlShortFormLength()) 235 + "' failed on backend " + backend.getName() + " but " + getSuccess() 236 + " succeeded (" + e + ")"; 237 logger.error(msg); 238 endUserLogger.error(Translate.get( 239 "loadbalancer.backend.disabling", backend.getName())); 240 throw new SQLException (msg); 241 } 242 finally 243 { 244 cm.releaseConnectionInAutoCommit(request, c); 245 } 246 } 247 248 private void executeInTransaction(BackendWorkerThread backendThread, 249 DatabaseBackend backend, AbstractConnectionManager cm, Trace logger) 250 throws SQLException 251 { 252 Connection c; 254 long tid = request.getTransactionId(); 255 256 try 257 { 258 c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(request, cm); 259 } 260 catch (UnreachableBackendException ube) 261 { 262 SQLException se = new SQLException ("Backend " + backend.getName() 263 + " is no more reachable."); 264 try 265 { 266 notifyFailure(backendThread, -1, se); 267 } 268 catch (SQLException ignore) 269 { 270 } 271 backendThread.getLoadBalancer().disableBackend(backend, true); 274 String msg = Translate.get( 275 "loadbalancer.backend.disabling.unreachable", backend.getName()); 276 logger.error(msg); 277 endUserLogger.error(msg); 278 throw se; 279 } 280 catch (NoTransactionStartWhenDisablingException e) 281 { 282 notifyCompletion(backendThread); 286 return; 287 } 288 catch (SQLException e1) 289 { 290 SQLException se = new SQLException ( 291 "Unable to get connection for transaction " + tid); 292 try 293 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 295 return; 296 } 297 catch (SQLException ignore) 298 { 299 } 300 backendThread.getLoadBalancer().disableBackend(backend, true); 303 String msg = "Request '" 304 + request.getSqlShortForm(backend.getSqlShortFormLength()) 305 + "' failed on backend " + backend.getName() + " but " + getSuccess() 306 + " succeeded (" + se + ")"; 307 logger.error(msg); 308 endUserLogger.error(Translate.get( 309 "loadbalancer.backend.disabling", backend.getName())); 310 throw new SQLException (msg); 311 } 312 313 if (c == null) 315 { SQLException se = new SQLException ( 317 "Unable to retrieve connection for transaction " + tid); 318 try 319 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, se)) 321 return; 322 } 323 catch (SQLException ignore) 324 { 325 } 326 backendThread.getLoadBalancer().disableBackend(backend, true); 329 String msg = "Request '" 330 + request.getSqlShortForm(backend.getSqlShortFormLength()) 331 + "' failed on backend " + backend.getName() + " but " + getSuccess() 332 + " succeeded (" + se + ")"; 333 logger.error(msg); 334 endUserLogger.error(Translate.get( 335 "loadbalancer.backend.disabling", backend.getName())); 336 throw new SQLException (msg); 337 } 338 339 try 341 { 342 result = AbstractLoadBalancer 343 .executeStatementExecuteUpdateWithKeysOnBackend(request, backend, 344 backendThread, c, metadataCache); 345 346 backend.updateDatabaseBackendSchema(request); 347 } 348 catch (Exception e) 349 { 350 try 351 { if (!notifyFailure(backendThread, request.getTimeout() * 1000L, e)) 353 { 354 result = null; 355 return; 356 } 357 } 358 catch (SQLException ignore) 359 { 360 } 361 backendThread.getLoadBalancer().disableBackend(backend, true); 364 String msg = "Request '" 365 + request.getSqlShortForm(backend.getSqlShortFormLength()) 366 + "' failed on backend " + backend.getName() + " but " + getSuccess() 367 + " succeeded (" + e + ")"; 368 logger.error(msg); 369 endUserLogger.error(Translate.get( 370 "loadbalancer.backend.disabling", backend.getName())); 371 throw new SQLException (msg); 372 } 373 } 374 375 378 public AbstractRequest getRequest() 379 { 380 return request; 381 } 382 383 388 public GeneratedKeysResult getResult() 389 { 390 return result; 391 } 392 393 396 public long getTransactionId() 397 { 398 return request.getTransactionId(); 399 } 400 401 404 public boolean isAutoCommit() 405 { 406 return request.isAutoCommit(); 407 } 408 409 412 public boolean equals(Object other) 413 { 414 if ((other == null) 415 || !(other instanceof StatementExecuteUpdateWithKeysTask)) 416 return false; 417 418 StatementExecuteUpdateWithKeysTask seuwk = (StatementExecuteUpdateWithKeysTask) other; 419 return this.request.equals(seuwk.getRequest()); 420 } 421 422 425 public int hashCode() 426 { 427 return (int) request.getId(); 428 } 429 430 433 public String toString() 434 { 435 if (request.isAutoCommit()) 436 return "Autocommit StatementExecuteUpdateWithKeysTask (" 437 + request.getUniqueKey() + ")"; 438 else 439 return "StatementExecuteUpdateWithKeysTask from transaction " 440 + request.getTransactionId() + " (" + request.getUniqueKey() + ")"; 441 } 442 443 } | Popular Tags |