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
00110
00111
00112
notifyCompletion();
00113
return;
00114 }
00115
00116
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
00141
if (c == null)
00142 {
00143 SQLException se =
new SQLException(
"No more connections");
00144
try
00145 {
00146
if (!
notifyFailure(backendThread, (
long)
request.getTimeout() * 1000,
00147 se))
00148
return;
00149 }
00150
catch (SQLException ignore)
00151 {
00152 }
00153
00154
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
00165
try
00166 {
00167
result =
new ControllerResultSet(
request,
AbstractLoadBalancer
00168 .executeUpdateRequestOnBackendWithKeys(
request, backend, c),
00169
metadataCache);
00170
00171
00172
if (request.isCreate())
00173 {
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 {
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 {
00209
if (!
notifyFailure(backendThread, (
long)
request.getTimeout() * 1000,
00210 e))
00211
return;
00212 }
00213
catch (SQLException ignore)
00214 {
00215 }
00216
00217
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 {
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
00242
00243
notifyCompletion();
00244
return;
00245 }
00246
00247
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
00271
if (c == null)
00272 {
00273 SQLException se =
new SQLException(
00274
"Unable to get connection for transaction " + tid);
00275
try
00276 {
00277
if (!
notifyFailure(backendThread,
00278 (
long)
request.getTimeout() * 1000, se))
00279
return;
00280 }
00281
catch (SQLException ignore)
00282 {
00283 }
00284
00285
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
00296 backend.
startTransaction(lTid);
00297 c.setAutoCommit(
false);
00298 }
00299
else
00300 {
00301 c = cm.
retrieveConnection(tid);
00302
00303
00304
if (c == null)
00305 {
00306 SQLException se =
new SQLException(
00307
"Unable to retrieve connection for transaction " + tid);
00308
try
00309 {
00310
if (!
notifyFailure(backendThread,
00311 (
long)
request.getTimeout() * 1000, se))
00312
return;
00313 }
00314
catch (SQLException ignore)
00315 {
00316 }
00317
00318
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
00330
try
00331 {
00332
result =
new ControllerResultSet(
request,
AbstractLoadBalancer
00333 .executeUpdateRequestOnBackendWithKeys(
request, backend, c),
00334
metadataCache);
00335
00336
00337
if (request.isCreate())
00338 {
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 {
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 {
00374
if (!
notifyFailure(backendThread, (
long)
request.getTimeout() * 1000,
00375 e))
00376
return;
00377 }
00378
catch (SQLException ignore)
00379 {
00380 }
00381
00382
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 }