src/org/objectweb/cjdbc/controller/loadbalancer/AbstractLoadBalancer.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.controller.loadbalancer; 00026 00027 import java.sql.CallableStatement; 00028 import java.sql.Connection; 00029 import java.sql.PreparedStatement; 00030 import java.sql.ResultSet; 00031 import java.sql.SQLException; 00032 import java.sql.Statement; 00033 import java.util.ArrayList; 00034 00035 import org.objectweb.cjdbc.common.exceptions.BadConnectionException; 00036 import org.objectweb.cjdbc.common.i18n.Translate; 00037 import org.objectweb.cjdbc.common.log.Trace; 00038 import org.objectweb.cjdbc.common.sql.AbstractRequest; 00039 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 00040 import org.objectweb.cjdbc.common.sql.SelectRequest; 00041 import org.objectweb.cjdbc.common.sql.StoredProcedure; 00042 import org.objectweb.cjdbc.common.sql.filters.MacrosHandler; 00043 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 00044 import org.objectweb.cjdbc.common.xml.XmlComponent; 00045 import org.objectweb.cjdbc.controller.backend.DatabaseBackend; 00046 import org.objectweb.cjdbc.controller.backend.DriverCompliance; 00047 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache; 00048 import org.objectweb.cjdbc.controller.requestmanager.TransactionMarkerMetaData; 00049 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet; 00050 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase; 00051 00064 public abstract class AbstractLoadBalancer implements XmlComponent 00065 { 00066 00067 // 00068 // How the code is organized ? 00069 // 00070 // 1. Member variables/Constructor 00071 // 2. Getter/Setter (possibly in alphabetical order) 00072 // 3. Request handling 00073 // 4. Transaction management 00074 // 5. Backend management 00075 // 6. Debug/Monitoring 00076 // 00077 00078 // Virtual Database this load balancer is attached to. 00079 protected VirtualDatabase vdb; 00080 protected int raidbLevel; 00081 protected int parsingGranularity; 00082 00083 protected static Trace logger = Trace 00084 .getLogger("org.objectweb.cjdbc.controller.loadbalancer"); 00085 00086 protected MacrosHandler macroHandler; 00087 00097 protected AbstractLoadBalancer(VirtualDatabase vdb, int raidbLevel, 00098 int parsingGranularity) throws SQLException 00099 { 00100 this.raidbLevel = raidbLevel; 00101 this.parsingGranularity = parsingGranularity; 00102 this.vdb = vdb; 00103 try 00104 { 00105 vdb.acquireReadLockBackendLists(); 00106 } 00107 catch (InterruptedException e) 00108 { 00109 String msg = Translate.get( 00110 "loadbalancer.backendlist.acquire.readlock.failed", e); 00111 logger.error(msg); 00112 throw new SQLException(msg); 00113 } 00114 int size = vdb.getBackends().size(); 00115 ArrayList backends = vdb.getBackends(); 00116 for (int i = 0; i < size; i++) 00117 { 00118 DatabaseBackend backend = (DatabaseBackend) backends.get(i); 00119 if (backend.isReadEnabled() || backend.isWriteEnabled()) 00120 { 00121 if (logger.isWarnEnabled()) 00122 logger.warn(Translate.get( 00123 "loadbalancer.constructor.backends.not.disabled", backend 00124 .getName())); 00125 backend.disable(); 00126 } 00127 } 00128 vdb.releaseReadLockBackendLists(); 00129 } 00130 00131 // 00132 // Getter/Setter methods 00133 // 00134 00140 public int getRAIDbLevel() 00141 { 00142 return raidbLevel; 00143 } 00144 00150 public void setRAIDbLevel(int raidbLevel) 00151 { 00152 this.raidbLevel = raidbLevel; 00153 } 00154 00160 public int getParsingGranularity() 00161 { 00162 return parsingGranularity; 00163 } 00164 00170 public void setParsingGranularity(int parsingGranularity) 00171 { 00172 this.parsingGranularity = parsingGranularity; 00173 } 00174 00175 // 00176 // Request Handling 00177 // 00178 00188 public abstract ControllerResultSet execReadRequest(SelectRequest request, 00189 MetadataCache metadataCache) throws SQLException; 00190 00201 public abstract int execWriteRequest(AbstractWriteRequest request) 00202 throws AllBackendsFailedException, SQLException; 00203 00215 public abstract ControllerResultSet execWriteRequestWithKeys( 00216 AbstractWriteRequest request, MetadataCache metadataCache) 00217 throws AllBackendsFailedException, SQLException; 00218 00228 public abstract ControllerResultSet execReadOnlyReadStoredProcedure( 00229 StoredProcedure proc, MetadataCache metadataCache) throws SQLException; 00230 00240 public abstract ControllerResultSet execReadStoredProcedure( 00241 StoredProcedure proc, MetadataCache metadataCache) throws SQLException; 00242 00250 public abstract int execWriteStoredProcedure(StoredProcedure proc) 00251 throws SQLException; 00252 00266 public static ControllerResultSet executeSelectRequestOnBackend( 00267 SelectRequest request, DatabaseBackend backend, Connection c, 00268 MetadataCache metadataCache) throws SQLException, BadConnectionException 00269 { 00270 ControllerResultSet rs = null; 00271 try 00272 { 00273 backend.addPendingReadRequest(request); 00274 String sql = request.getSQL(); 00275 // Rewrite the query if needed 00276 sql = backend.rewriteQuery(sql); 00277 00278 Statement s; // Can also be used as a PreparedStatement 00279 if (request.isDriverProcessed() || (request.getSqlSkeleton() == null)) 00280 s = c.createStatement(); 00281 else 00282 { 00283 s = c.prepareStatement(request.getSqlSkeleton()); 00284 org.objectweb.cjdbc.driver.PreparedStatement.setPreparedStatement(sql, 00285 (PreparedStatement) s); 00286 } 00287 00288 // Execute the query 00289 DriverCompliance driverCompliance = backend.getDriverCompliance(); 00290 if (driverCompliance.supportSetQueryTimeout()) 00291 s.setQueryTimeout(request.getTimeout()); 00292 if ((request.getCursorName() != null) 00293 && (driverCompliance.supportSetCursorName())) 00294 s.setCursorName(request.getCursorName()); 00295 if ((request.getFetchSize() != 0) 00296 && driverCompliance.supportSetFetchSize()) 00297 s.setFetchSize(request.getFetchSize()); 00298 if ((request.getMaxRows() > 0) && driverCompliance.supportSetMaxRows()) 00299 s.setMaxRows(request.getMaxRows()); 00300 if (request.isDriverProcessed() || (request.getSqlSkeleton() == null)) 00301 rs = new ControllerResultSet(request, s.executeQuery(sql), 00302 metadataCache); 00303 else 00304 rs = new ControllerResultSet(request, ((PreparedStatement) s) 00305 .executeQuery(), metadataCache); 00306 } 00307 catch (SQLException e) 00308 { // Something bad happened 00309 if (backend.isValidConnection(c)) 00310 throw e; // Connection is valid, throw the exception 00311 else 00312 throw new BadConnectionException(e); 00313 } 00314 finally 00315 { 00316 backend.removePendingRequest(request); 00317 } 00318 return rs; 00319 } 00320 00333 public static int executeUpdateRequestOnBackend(AbstractWriteRequest request, 00334 DatabaseBackend backend, Connection c) throws SQLException, 00335 BadConnectionException 00336 { 00337 try 00338 { 00339 backend.addPendingWriteRequest(request); 00340 String sql = request.getSQL(); 00341 // Rewrite the query if needed 00342 sql = backend.rewriteQuery(sql); 00343 00344 Statement s; // Can also be used as a PreparedStatement 00345 if (request.isDriverProcessed() || (request.getSqlSkeleton() == null)) 00346 s = c.createStatement(); 00347 else 00348 { 00349 s = c.prepareStatement(request.getSqlSkeleton()); 00350 org.objectweb.cjdbc.driver.PreparedStatement.setPreparedStatement(sql, 00351 (PreparedStatement) s); 00352 } 00353 00354 // Execute the query 00355 DriverCompliance driverCompliance = backend.getDriverCompliance(); 00356 if (driverCompliance.supportSetQueryTimeout()) 00357 s.setQueryTimeout(request.getTimeout()); 00358 00359 if (request.isDriverProcessed() || (request.getSqlSkeleton() == null)) 00360 return s.executeUpdate(sql); 00361 else 00362 return ((PreparedStatement) s).executeUpdate(); 00363 } 00364 catch (SQLException e) 00365 { // Something bad happened 00366 if (backend.isValidConnection(c)) 00367 throw e; // Connection is valid, throw the exception 00368 else 00369 throw new BadConnectionException(e); 00370 } 00371 finally 00372 { 00373 backend.removePendingRequest(request); 00374 } 00375 } 00376 00389 public static ResultSet executeUpdateRequestOnBackendWithKeys( 00390 AbstractWriteRequest request, DatabaseBackend backend, Connection c) 00391 throws SQLException, BadConnectionException 00392 { 00393 try 00394 { 00395 backend.addPendingWriteRequest(request); 00396 String sql = request.getSQL(); 00397 // Rewrite the query if needed 00398 sql = backend.rewriteQuery(sql); 00399 00400 Statement s = c.createStatement(); 00401 00402 // Execute the query 00403 DriverCompliance driverCompliance = backend.getDriverCompliance(); 00404 if (driverCompliance.supportSetQueryTimeout()) 00405 s.setQueryTimeout(request.getTimeout()); 00406 00407 s.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); 00408 return s.getGeneratedKeys(); 00409 } 00410 catch (SQLException e) 00411 { // Something bad happened 00412 if (backend.isValidConnection(c)) 00413 throw e; // Connection is valid, throw the exception 00414 else 00415 throw new BadConnectionException(e); 00416 } 00417 finally 00418 { 00419 backend.removePendingRequest(request); 00420 } 00421 } 00422 00435 public static ControllerResultSet executeReadStoredProcedureOnBackend( 00436 StoredProcedure proc, DatabaseBackend backend, Connection c, 00437 MetadataCache metadataCache) throws SQLException, BadConnectionException 00438 { 00439 try 00440 { 00441 backend.addPendingReadRequest(proc); 00442 00443 // We suppose here that the request does not modify the schema since 00444 // it is a read-only query. 00445 CallableStatement cs; 00446 if (proc.isDriverProcessed()) 00447 cs = c.prepareCall(proc.getSQL()); 00448 else 00449 { 00450 cs = c.prepareCall(proc.getSqlSkeleton()); 00451 org.objectweb.cjdbc.driver.PreparedStatement.setPreparedStatement(proc 00452 .getSQL(), cs); 00453 } 00454 if (backend.getDriverCompliance().supportSetQueryTimeout()) 00455 cs.setQueryTimeout(proc.getTimeout()); 00456 if ((proc.getMaxRows() > 0) 00457 && backend.getDriverCompliance().supportSetMaxRows()) 00458 cs.setMaxRows(proc.getMaxRows()); 00459 return new ControllerResultSet(proc, cs.executeQuery(), metadataCache); 00460 } 00461 catch (SQLException e) 00462 { // Something bad happened 00463 if (backend.isValidConnection(c)) 00464 throw e; // Connection is valid, throw the exception 00465 else 00466 throw new BadConnectionException(e); 00467 } 00468 finally 00469 { 00470 backend.removePendingRequest(proc); 00471 } 00472 } 00473 00485 public static int executeWriteStoredProcedureOnBackend(StoredProcedure proc, 00486 DatabaseBackend backend, Connection c) throws SQLException, 00487 BadConnectionException 00488 { 00489 try 00490 { 00491 backend.addPendingWriteRequest(proc); 00492 00493 // We suppose here that the request does not modify the schema since 00494 // it is a read-only query. 00495 CallableStatement cs; 00496 if (proc.isDriverProcessed()) 00497 cs = c.prepareCall(proc.getSQL()); 00498 else 00499 { 00500 cs = c.prepareCall(proc.getSqlSkeleton()); 00501 org.objectweb.cjdbc.driver.PreparedStatement.setPreparedStatement(proc 00502 .getSQL(), cs); 00503 } 00504 if (backend.getDriverCompliance().supportSetQueryTimeout()) 00505 cs.setQueryTimeout(proc.getTimeout()); 00506 if ((proc.getMaxRows() > 0) 00507 && backend.getDriverCompliance().supportSetMaxRows()) 00508 cs.setMaxRows(proc.getMaxRows()); 00509 return cs.executeUpdate(); 00510 } 00511 catch (SQLException e) 00512 { // Something bad happened 00513 if (backend.isValidConnection(c)) 00514 throw e; // Connection is valid, throw the exception 00515 else 00516 throw new BadConnectionException(e); 00517 } 00518 finally 00519 { 00520 backend.removePendingRequest(proc); 00521 } 00522 } 00523 00524 // 00525 // Transaction management 00526 // 00527 00534 public abstract void begin(TransactionMarkerMetaData tm) throws SQLException; 00535 00544 public abstract void commit(TransactionMarkerMetaData tm) 00545 throws AllBackendsFailedException, SQLException; 00546 00555 public abstract void rollback(TransactionMarkerMetaData tm) 00556 throws AllBackendsFailedException, SQLException; 00557 00558 // 00559 // Backends management 00560 // 00561 00571 public abstract void enableBackend(DatabaseBackend db, boolean writeEnabled) 00572 throws SQLException; 00573 00583 public abstract void disableBackend(DatabaseBackend db) throws SQLException; 00584 00592 public void setWeight(String name, int w) throws SQLException 00593 { 00594 throw new SQLException("Weight is not supported by this load balancer"); 00595 } 00596 00597 // 00598 // Debug/Monitoring 00599 // 00600 00606 public abstract String getInformation(); 00607 00613 public abstract String getXmlImpl(); 00614 00622 public void setMacroHandler(MacrosHandler handler) 00623 { 00624 this.macroHandler = handler; 00625 } 00626 00635 public void handleMacros(AbstractRequest request) 00636 { 00637 if (macroHandler == null) 00638 return; 00639 00640 if (request.isDriverProcessed() || (request.getSqlSkeleton() == null)) 00641 request.setSQL(macroHandler.processMacros(request.getSQL())); 00642 else 00643 request.setSqlSkeleton(macroHandler.processMacros(request 00644 .getSqlSkeleton())); 00645 } 00646 00650 public String getXml() 00651 { 00652 StringBuffer info = new StringBuffer(); 00653 info.append("<" + DatabasesXmlTags.ELT_LoadBalancer + ">"); 00654 info.append(getXmlImpl()); 00655 info.append("</" + DatabasesXmlTags.ELT_LoadBalancer + ">"); 00656 return info.toString(); 00657 } 00658 00659 }

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