src/org/objectweb/cjdbc/controller/loadbalancer/tasks/WriteRequestWithKeysTask.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.controller.loadbalancer.tasks; 00026 00027 import java.sql.Connection; 00028 import java.sql.SQLException; 00029 00030 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException; 00031 import org.objectweb.cjdbc.common.i18n.Translate; 00032 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 00033 import org.objectweb.cjdbc.common.sql.CreateRequest; 00034 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema; 00035 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable; 00036 import org.objectweb.cjdbc.controller.backend.DatabaseBackend; 00037 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache; 00038 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager; 00039 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer; 00040 import org.objectweb.cjdbc.controller.loadbalancer.BackendWorkerThread; 00041 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet; 00042 00051 public class WriteRequestWithKeysTask extends AbstractTask 00052 { 00053 private AbstractWriteRequest request; 00054 private ControllerResultSet result; 00055 private MetadataCache metadataCache; 00056 00065 public WriteRequestWithKeysTask(int nbToComplete, int totalNb, 00066 AbstractWriteRequest request, MetadataCache metadataCache) 00067 { 00068 super(nbToComplete, totalNb); 00069 this.request = request; 00070 this.metadataCache = metadataCache; 00071 } 00072 00079 public void execute(BackendWorkerThread backendThread) throws SQLException 00080 { 00081 DatabaseBackend backend = backendThread.getBackend(); 00082 00083 if (!backend.getDriverCompliance().supportGetGeneratedKeys()) 00084 throw new SQLException(Translate.get( 00085 "loadbalancer.backend.autogeneratedkeys.unsupported", backend 00086 .getName())); 00087 00088 AbstractConnectionManager cm = backend.getConnectionManager(request 00089 .getLogin()); 00090 if (cm == null) 00091 { 00092 SQLException se = new SQLException( 00093 "No Connection Manager for Virtual Login:" + request.getLogin()); 00094 try 00095 { 00096 notifyFailure(backendThread, 1, se); 00097 } 00098 catch (SQLException ignore) 00099 { 00100 00101 } 00102 throw se; 00103 } 00104 00105 if (request.isAutoCommit()) 00106 { 00107 if (backend.isDisabling()) 00108 { 00109 // Backend is disabling, we do not execute queries except the one in the 00110 // transaction we already started. Just notify the completion for the 00111 // others. 00112 notifyCompletion(); 00113 return; 00114 } 00115 00116 // Use a connection just for this request 00117 Connection c = null; 00118 try 00119 { 00120 c = cm.getConnection(); 00121 } 00122 catch (UnreachableBackendException e1) 00123 { 00124 SQLException se = new SQLException("Backend " + backend.getName() 00125 + " is no more reachable."); 00126 try 00127 { 00128 notifyFailure(backendThread, 1, se); 00129 } 00130 catch (SQLException ignore) 00131 { 00132 } 00133 backendThread.getLogger().error( 00134 "Disabling backend " + backend.getName() 00135 + " because it is no more reachable."); 00136 backend.disable(); 00137 throw se; 00138 } 00139 00140 // Sanity check 00141 if (c == null) 00142 { 00143 SQLException se = new SQLException("No more connections"); 00144 try 00145 { // All backends failed, just ignore 00146 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000, 00147 se)) 00148 return; 00149 } 00150 catch (SQLException ignore) 00151 { 00152 } 00153 // Disable this backend (it is no more in sync) by killing the backend 00154 // thread 00155 backendThread.kill(); 00156 String msg = "Request '" 00157 + request.getSQLShortForm(backend.getSQLShortFormLength()) 00158 + "' failed on backend " + backend.getName() + " but " 00159 + getSuccess() + " succeeded (" + se + ")"; 00160 backendThread.getLogger().error(msg); 00161 throw new SQLException(msg); 00162 } 00163 00164 // Execute Query 00165 try 00166 { 00167 result = new ControllerResultSet(request, AbstractLoadBalancer 00168 .executeUpdateRequestOnBackendWithKeys(request, backend, c), 00169 metadataCache); 00170 00171 // Update schema 00172 if (request.isCreate()) 00173 { // Add the table to the schema 00174 DatabaseSchema dbs = backend.getDatabaseSchema(); 00175 if (dbs != null) 00176 { 00177 DatabaseTable t = ((CreateRequest) request).getDatabaseTable(); 00178 if (t != null) 00179 { 00180 dbs.addTable(t); 00181 if (backendThread.getLogger().isDebugEnabled()) 00182 backendThread.getLogger().debug( 00183 "Added table '" + request.getTableName() 00184 + "' to backend database schema"); 00185 } 00186 } 00187 } 00188 else if (request.isDrop()) 00189 { // Delete the table from the schema 00190 DatabaseSchema dbs = backend.getDatabaseSchema(); 00191 if (dbs != null) 00192 { 00193 DatabaseTable t = dbs.getTable(request.getTableName()); 00194 if (t != null) 00195 { 00196 dbs.removeTable(t); 00197 if (backendThread.getLogger().isDebugEnabled()) 00198 backendThread.getLogger().debug( 00199 "Removed table '" + request.getTableName() 00200 + "' from backend database schema"); 00201 } 00202 } 00203 } 00204 } 00205 catch (Exception e) 00206 { 00207 try 00208 { // All backends failed, just ignore 00209 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000, 00210 e)) 00211 return; 00212 } 00213 catch (SQLException ignore) 00214 { 00215 } 00216 // Disable this backend (it is no more in sync) by killing the backend 00217 // thread 00218 backendThread.kill(); 00219 String msg = "Request '" 00220 + request.getSQLShortForm(backend.getSQLShortFormLength()) 00221 + "' failed on backend " + backend.getName() + " but " 00222 + getSuccess() + " succeeded (" + e + ")"; 00223 backendThread.getLogger().error(msg); 00224 throw new SQLException(msg); 00225 } 00226 finally 00227 { 00228 cm.releaseConnection(c); 00229 } 00230 } 00231 else 00232 { // Re-use the connection used by this transaction 00233 Connection c; 00234 long tid = request.getTransactionId(); 00235 Long lTid = new Long(tid); 00236 00237 if (!backend.isStartedTransaction(lTid)) 00238 { 00239 if (backend.isDisabling()) 00240 { 00241 // Backend is disabling, we do not start new transactions, just notify 00242 // the completion for the others 00243 notifyCompletion(); 00244 return; 00245 } 00246 00247 // Transaction has not been started yet, this is a lazy begin 00248 try 00249 { 00250 c = cm.getConnection(tid); 00251 } 00252 catch (UnreachableBackendException e1) 00253 { 00254 SQLException se = new SQLException("Backend " + backend.getName() 00255 + " is no more reachable."); 00256 try 00257 { 00258 notifyFailure(backendThread, 1, se); 00259 } 00260 catch (SQLException ignore) 00261 { 00262 } 00263 backendThread.getLogger().error( 00264 "Disabling backend " + backend.getName() 00265 + " because it is no more reachable."); 00266 backend.disable(); 00267 throw se; 00268 } 00269 00270 // Sanity check 00271 if (c == null) 00272 { // Bad connection 00273 SQLException se = new SQLException( 00274 "Unable to get connection for transaction " + tid); 00275 try 00276 { // All backends failed, just ignore 00277 if (!notifyFailure(backendThread, 00278 (long) request.getTimeout() * 1000, se)) 00279 return; 00280 } 00281 catch (SQLException ignore) 00282 { 00283 } 00284 // Disable this backend (it is no more in sync) by killing the 00285 // backend thread 00286 backendThread.kill(); 00287 String msg = "Request '" 00288 + request.getSQLShortForm(backend.getSQLShortFormLength()) 00289 + "' failed on backend " + backend.getName() + " but " 00290 + getSuccess() + " succeeded (" + se + ")"; 00291 backendThread.getLogger().error(msg); 00292 throw new SQLException(msg); 00293 } 00294 00295 // begin transaction 00296 backend.startTransaction(lTid); 00297 c.setAutoCommit(false); 00298 } 00299 else 00300 { // Transaction has already been started, retrieve connection 00301 c = cm.retrieveConnection(tid); 00302 00303 // Sanity check 00304 if (c == null) 00305 { // Bad connection 00306 SQLException se = new SQLException( 00307 "Unable to retrieve connection for transaction " + tid); 00308 try 00309 { // All backends failed, just ignore 00310 if (!notifyFailure(backendThread, 00311 (long) request.getTimeout() * 1000, se)) 00312 return; 00313 } 00314 catch (SQLException ignore) 00315 { 00316 } 00317 // Disable this backend (it is no more in sync) by killing the 00318 // backend thread 00319 backendThread.kill(); 00320 String msg = "Request '" 00321 + request.getSQLShortForm(backend.getSQLShortFormLength()) 00322 + "' failed on backend " + backend.getName() + " but " 00323 + getSuccess() + " succeeded (" + se + ")"; 00324 backendThread.getLogger().error(msg); 00325 throw new SQLException(msg); 00326 } 00327 } 00328 00329 // Execute Query 00330 try 00331 { 00332 result = new ControllerResultSet(request, AbstractLoadBalancer 00333 .executeUpdateRequestOnBackendWithKeys(request, backend, c), 00334 metadataCache); 00335 00336 // Update schema 00337 if (request.isCreate()) 00338 { // Add the table to the schema 00339 DatabaseSchema dbs = backend.getDatabaseSchema(); 00340 if (dbs != null) 00341 { 00342 DatabaseTable t = ((CreateRequest) request).getDatabaseTable(); 00343 if (t != null) 00344 { 00345 dbs.addTable(t); 00346 if (backendThread.getLogger().isDebugEnabled()) 00347 backendThread.getLogger().debug( 00348 "Added table '" + request.getTableName() 00349 + "' to backend database schema"); 00350 } 00351 } 00352 } 00353 else if (request.isDrop()) 00354 { // Delete the table from the schema 00355 DatabaseSchema dbs = backend.getDatabaseSchema(); 00356 if (dbs != null) 00357 { 00358 DatabaseTable t = dbs.getTable(request.getTableName()); 00359 if (t != null) 00360 { 00361 dbs.removeTable(t); 00362 if (backendThread.getLogger().isDebugEnabled()) 00363 backendThread.getLogger().debug( 00364 "Removed table '" + request.getTableName() 00365 + "' from backend database schema"); 00366 } 00367 } 00368 } 00369 } 00370 catch (Exception e) 00371 { 00372 try 00373 { // All backends failed, just ignore 00374 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000, 00375 e)) 00376 return; 00377 } 00378 catch (SQLException ignore) 00379 { 00380 } 00381 // Disable this backend (it is no more in sync) by killing the backend 00382 // thread 00383 backendThread.kill(); 00384 String msg = "Request '" 00385 + request.getSQLShortForm(backend.getSQLShortFormLength()) 00386 + "' failed on backend " + backend.getName() + " but " 00387 + getSuccess() + " succeeded (" + e + ")"; 00388 backendThread.getLogger().error(msg); 00389 throw new SQLException(msg); 00390 } 00391 } 00392 notifySuccess(); 00393 } 00394 00400 public ControllerResultSet getResult() 00401 { 00402 return result; 00403 } 00404 00408 public String toString() 00409 { 00410 if (request.isAutoCommit()) 00411 return "WriteWithKeys Autocommit Task (" + request.getSQL() + ")"; 00412 else 00413 return "WriteWithKeys Task from transaction:" 00414 + request.getTransactionId() + "(" + request.getSQL() + ")"; 00415 } 00416 00417 }

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