00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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.NoTransactionStartWhenDisablingException;
00031 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException;
00032 import org.objectweb.cjdbc.common.i18n.Translate;
00033 import org.objectweb.cjdbc.common.log.Trace;
00034 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
00035 import org.objectweb.cjdbc.common.sql.CreateRequest;
00036 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema;
00037 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable;
00038 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
00039 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache;
00040 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager;
00041 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer;
00042 import org.objectweb.cjdbc.controller.loadbalancer.BackendWorkerThread;
00043 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 public class WriteRequestWithKeysTask extends AbstractTask
00054 {
00055 private AbstractWriteRequest request;
00056 private ControllerResultSet result;
00057 private MetadataCache metadataCache;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 public WriteRequestWithKeysTask(int nbToComplete, int totalNb,
00068 AbstractWriteRequest request, MetadataCache metadataCache)
00069 {
00070 super(nbToComplete, totalNb);
00071 this.request = request;
00072 this.metadataCache = metadataCache;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 public void executeTask(BackendWorkerThread backendThread)
00082 throws SQLException
00083 {
00084 DatabaseBackend backend = backendThread.getBackend();
00085
00086 if (!backend.getDriverCompliance().supportGetGeneratedKeys())
00087 throw new SQLException(Translate.get(
00088 "loadbalancer.backend.autogeneratedkeys.unsupported", backend
00089 .getName()));
00090
00091 AbstractConnectionManager cm = backend.getConnectionManager(request
00092 .getLogin());
00093 if (cm == null)
00094 {
00095 SQLException se = new SQLException(
00096 "No Connection Manager for Virtual Login:" + request.getLogin());
00097 try
00098 {
00099 notifyFailure(backendThread, 1, se);
00100 }
00101 catch (SQLException ignore)
00102 {
00103
00104 }
00105 throw se;
00106 }
00107
00108 Trace logger = backendThread.getLogger();
00109 if (request.isAutoCommit())
00110 {
00111 if (backend.isDisabling())
00112 {
00113
00114
00115 notifyCompletion();
00116 return;
00117 }
00118
00119
00120 Connection c = null;
00121 try
00122 {
00123 c = cm.getConnection();
00124 }
00125 catch (UnreachableBackendException e1)
00126 {
00127 SQLException se = new SQLException("Backend " + backend.getName()
00128 + " is no more reachable.");
00129 try
00130 {
00131 notifyFailure(backendThread, 1, se);
00132 }
00133 catch (SQLException ignore)
00134 {
00135 }
00136
00137
00138 backendThread.kill();
00139 logger.error("Disabling backend " + backend.getName()
00140 + " because it is no more reachable.");
00141 throw se;
00142 }
00143
00144
00145 if (c == null)
00146 {
00147 SQLException se = new SQLException("No more connections");
00148 try
00149 {
00150 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
00151 se))
00152 return;
00153 }
00154 catch (SQLException ignore)
00155 {
00156 }
00157
00158
00159 backendThread.kill();
00160 String msg = "Request '"
00161 + request.getSQLShortForm(backend.getSQLShortFormLength())
00162 + "' failed on backend " + backend.getName() + " but "
00163 + getSuccess() + " succeeded (" + se + ")";
00164 logger.error(msg);
00165 throw new SQLException(msg);
00166 }
00167
00168
00169 try
00170 {
00171 result = AbstractLoadBalancer.executeUpdateRequestOnBackendWithKeys(
00172 request, backend, c, metadataCache);
00173
00174
00175 if (request.isCreate())
00176 {
00177 DatabaseSchema dbs = backend.getDatabaseSchema();
00178 if (dbs != null)
00179 {
00180 DatabaseTable t = ((CreateRequest) request).getDatabaseTable();
00181 if (t != null)
00182 {
00183 dbs.addTable(t);
00184 if (logger.isDebugEnabled())
00185 logger.debug("Added table '" + request.getTableName()
00186 + "' to backend database schema");
00187 }
00188 }
00189 }
00190 else if (request.isDrop())
00191 {
00192 DatabaseSchema dbs = backend.getDatabaseSchema();
00193 if (dbs != null)
00194 {
00195 DatabaseTable t = dbs.getTable(request.getTableName());
00196 if (t != null)
00197 {
00198 dbs.removeTable(t);
00199 if (logger.isDebugEnabled())
00200 logger.debug("Removed table '" + request.getTableName()
00201 + "' from backend database schema");
00202 }
00203 }
00204 }
00205 }
00206 catch (Exception e)
00207 {
00208 try
00209 {
00210 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
00211 e))
00212 return;
00213 }
00214 catch (SQLException ignore)
00215 {
00216 }
00217
00218
00219 backendThread.kill();
00220 String msg = "Request '"
00221 + request.getSQLShortForm(backend.getSQLShortFormLength())
00222 + "' failed on backend " + backend.getName() + " but "
00223 + getSuccess() + " succeeded (" + e + ")";
00224 logger.error(msg);
00225 throw new SQLException(msg);
00226 }
00227 finally
00228 {
00229 cm.releaseConnection(c);
00230 }
00231 }
00232 else
00233 {
00234 Connection c;
00235 long tid = request.getTransactionId();
00236 Long lTid = new Long(tid);
00237
00238 try
00239 {
00240 c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(lTid, cm);
00241 }
00242 catch (UnreachableBackendException ube)
00243 {
00244 SQLException se = new SQLException("Backend " + backend.getName()
00245 + " is no more reachable.");
00246 try
00247 {
00248 notifyFailure(backendThread, 1, se);
00249 }
00250 catch (SQLException ignore)
00251 {
00252 }
00253
00254
00255 backendThread.kill();
00256 logger.error("Disabling backend " + backend.getName()
00257 + " because it is no more reachable.");
00258 throw se;
00259 }
00260 catch (NoTransactionStartWhenDisablingException e)
00261 {
00262
00263
00264
00265 notifyCompletion();
00266 return;
00267 }
00268 catch (SQLException e1)
00269 {
00270 SQLException se = new SQLException(
00271 "Unable to get connection for transaction " + tid);
00272 try
00273 {
00274 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
00275 se))
00276 return;
00277 }
00278 catch (SQLException ignore)
00279 {
00280 }
00281
00282
00283 backendThread.kill();
00284 String msg = "Request '"
00285 + request.getSQLShortForm(backend.getSQLShortFormLength())
00286 + "' failed on backend " + backend.getName() + " but "
00287 + getSuccess() + " succeeded (" + se + ")";
00288 logger.error(msg);
00289 throw new SQLException(msg);
00290 }
00291
00292
00293 if (c == null)
00294 {
00295 SQLException se = new SQLException(
00296 "Unable to retrieve connection for transaction " + tid);
00297 try
00298 {
00299 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
00300 se))
00301 return;
00302 }
00303 catch (SQLException ignore)
00304 {
00305 }
00306
00307
00308 backendThread.kill();
00309 String msg = "Request '"
00310 + request.getSQLShortForm(backend.getSQLShortFormLength())
00311 + "' failed on backend " + backend.getName() + " but "
00312 + getSuccess() + " succeeded (" + se + ")";
00313 logger.error(msg);
00314 throw new SQLException(msg);
00315 }
00316
00317
00318 try
00319 {
00320 result = AbstractLoadBalancer.executeUpdateRequestOnBackendWithKeys(
00321 request, backend, c, metadataCache);
00322
00323
00324 if (request.isCreate())
00325 {
00326 DatabaseSchema dbs = backend.getDatabaseSchema();
00327 if (dbs != null)
00328 {
00329 DatabaseTable t = ((CreateRequest) request).getDatabaseTable();
00330 if (t != null)
00331 {
00332 dbs.addTable(t);
00333 if (logger.isDebugEnabled())
00334 logger.debug("Added table '" + request.getTableName()
00335 + "' to backend database schema");
00336 }
00337 }
00338 }
00339 else if (request.isDrop())
00340 {
00341 DatabaseSchema dbs = backend.getDatabaseSchema();
00342 if (dbs != null)
00343 {
00344 DatabaseTable t = dbs.getTable(request.getTableName());
00345 if (t != null)
00346 {
00347 dbs.removeTable(t);
00348 if (logger.isDebugEnabled())
00349 logger.debug("Removed table '" + request.getTableName()
00350 + "' from backend database schema");
00351 }
00352 }
00353 }
00354 }
00355 catch (Exception e)
00356 {
00357 try
00358 {
00359 if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
00360 e))
00361 return;
00362 }
00363 catch (SQLException ignore)
00364 {
00365 }
00366
00367
00368 backendThread.kill();
00369 String msg = "Request '"
00370 + request.getSQLShortForm(backend.getSQLShortFormLength())
00371 + "' failed on backend " + backend.getName() + " but "
00372 + getSuccess() + " succeeded (" + e + ")";
00373 logger.error(msg);
00374 throw new SQLException(msg);
00375 }
00376 }
00377 notifySuccess();
00378 }
00379
00380
00381
00382
00383
00384
00385 public ControllerResultSet getResult()
00386 {
00387 return result;
00388 }
00389
00390
00391
00392
00393 public String toString()
00394 {
00395 if (request.isAutoCommit())
00396 return "WriteWithKeys Autocommit Task (" + request.getSQL() + ")";
00397 else
00398 return "WriteWithKeys Task from transaction:"
00399 + request.getTransactionId() + "(" + request.getSQL() + ")";
00400 }
00401
00402 }