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.log.Trace;
00033 import org.objectweb.cjdbc.common.sql.StoredProcedure;
00034 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
00035 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache;
00036 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager;
00037 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer;
00038 import org.objectweb.cjdbc.controller.loadbalancer.BackendWorkerThread;
00039 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
00040
00041
00042
00043
00044
00045
00046
00047 public class ReadStoredProcedureTask extends AbstractTask
00048 {
00049 private StoredProcedure proc;
00050 private ControllerResultSet result;
00051 private MetadataCache metadataCache;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 public ReadStoredProcedureTask(int nbToComplete, int totalNb,
00062 StoredProcedure proc, MetadataCache metadataCache)
00063 {
00064 super(nbToComplete, totalNb);
00065 this.proc = proc;
00066 this.metadataCache = metadataCache;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076 public void executeTask(BackendWorkerThread backendThread)
00077 throws SQLException
00078 {
00079 DatabaseBackend backend = backendThread.getBackend();
00080
00081 AbstractConnectionManager cm = backend
00082 .getConnectionManager(proc.getLogin());
00083 if (cm == null)
00084 {
00085 SQLException se = new SQLException(
00086 "No Connection Manager for Virtual Login:" + proc.getLogin());
00087 try
00088 {
00089 notifyFailure(backendThread, 1, se);
00090 }
00091 catch (SQLException ignore)
00092 {
00093
00094 }
00095 throw se;
00096 }
00097
00098 Trace logger = backendThread.getLogger();
00099 if (proc.isAutoCommit())
00100 {
00101 Connection c = null;
00102 try
00103 {
00104 c = cm.getConnection();
00105 }
00106 catch (UnreachableBackendException e1)
00107 {
00108 SQLException se = new SQLException("Backend " + backend.getName()
00109 + " is no more reachable.");
00110 try
00111 {
00112 notifyFailure(backendThread, 1, se);
00113 }
00114 catch (SQLException ignore)
00115 {
00116 }
00117
00118
00119 backendThread.kill();
00120 logger.error("Disabling backend " + backend.getName()
00121 + " because it is no more reachable.");
00122 throw se;
00123 }
00124
00125
00126 if (c == null)
00127 {
00128 SQLException se = new SQLException("No more connections");
00129 try
00130 {
00131 if (!notifyFailure(backendThread, (long) proc.getTimeout() * 1000, se))
00132 return;
00133 }
00134 catch (SQLException ignore)
00135 {
00136 }
00137
00138
00139 backendThread.kill();
00140 String msg = "Stored procedure '"
00141 + proc.getSQLShortForm(backend.getSQLShortFormLength())
00142 + "' failed on backend " + backend.getName() + " but "
00143 + getSuccess() + " succeeded (" + se + ")";
00144 logger.error(msg);
00145 throw new SQLException(msg);
00146 }
00147
00148
00149 try
00150 {
00151 result = AbstractLoadBalancer.executeReadStoredProcedureOnBackend(proc,
00152 backend, c, metadataCache);
00153 }
00154 catch (Exception e)
00155 {
00156 try
00157 {
00158 if (!notifyFailure(backendThread, (long) proc.getTimeout() * 1000, e))
00159 return;
00160 }
00161 catch (SQLException ignore)
00162 {
00163 }
00164
00165
00166 backendThread.kill();
00167 String msg = "Stored procedure '"
00168 + proc.getSQLShortForm(backend.getSQLShortFormLength())
00169 + "' failed on backend " + backend.getName() + " but "
00170 + getSuccess() + " succeeded (" + e + ")";
00171 logger.error(msg);
00172 throw new SQLException(msg);
00173 }
00174 finally
00175 {
00176 cm.releaseConnection(c);
00177 }
00178 }
00179 else
00180 {
00181 Connection c;
00182 long tid = proc.getTransactionId();
00183 Long lTid = new Long(tid);
00184
00185 try
00186 {
00187 c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(lTid, cm);
00188 }
00189 catch (UnreachableBackendException ube)
00190 {
00191 SQLException se = new SQLException("Backend " + backend.getName()
00192 + " is no more reachable.");
00193 try
00194 {
00195 notifyFailure(backendThread, 1, se);
00196 }
00197 catch (SQLException ignore)
00198 {
00199 }
00200
00201
00202 backendThread.kill();
00203 logger.error("Disabling backend " + backend.getName()
00204 + " because it is no more reachable.");
00205 throw se;
00206 }
00207 catch (NoTransactionStartWhenDisablingException e)
00208 {
00209 logger
00210 .error("Disabling backend "
00211 + backend.getName()
00212 + " has been assigned a select request but it cannot start a new transaction for it.");
00213 notifyFailure(backendThread, (long) proc.getTimeout() * 1000, e);
00214 return;
00215 }
00216 catch (SQLException e1)
00217 {
00218 SQLException se = new SQLException(
00219 "Unable to get connection for transaction " + tid);
00220 try
00221 {
00222 if (!notifyFailure(backendThread, (long) proc.getTimeout() * 1000, se))
00223 return;
00224 }
00225 catch (SQLException ignore)
00226 {
00227 }
00228
00229
00230 backendThread.kill();
00231 String msg = "Request '"
00232 + proc.getSQLShortForm(backend.getSQLShortFormLength())
00233 + "' failed on backend " + backend.getName() + " but "
00234 + getSuccess() + " succeeded (" + se + ")";
00235 logger.error(msg);
00236 throw new SQLException(msg);
00237 }
00238
00239
00240 if (c == null)
00241 {
00242 SQLException se = new SQLException(
00243 "Unable to retrieve connection for transaction " + tid);
00244 try
00245 {
00246 if (!notifyFailure(backendThread, (long) proc.getTimeout() * 1000, se))
00247 return;
00248 }
00249 catch (SQLException ignore)
00250 {
00251 }
00252
00253
00254 backendThread.kill();
00255 String msg = "Request '"
00256 + proc.getSQLShortForm(backend.getSQLShortFormLength())
00257 + "' failed on backend " + backend.getName() + " but "
00258 + getSuccess() + " succeeded (" + se + ")";
00259 logger.error(msg);
00260 throw new SQLException(msg);
00261 }
00262
00263
00264 try
00265 {
00266 result = AbstractLoadBalancer.executeReadStoredProcedureOnBackend(proc,
00267 backend, c, metadataCache);
00268
00269
00270
00271 }
00272 catch (Exception e)
00273 {
00274 try
00275 {
00276 if (!notifyFailure(backendThread, (long) proc.getTimeout() * 1000, e))
00277 return;
00278 }
00279 catch (SQLException ignore)
00280 {
00281 }
00282
00283
00284 backendThread.kill();
00285 String msg = "Stored procedure '"
00286 + proc.getSQLShortForm(backend.getSQLShortFormLength())
00287 + "' failed on backend " + backend.getName() + " but "
00288 + getSuccess() + " succeeded (" + e + ")";
00289 logger.error(msg);
00290 throw new SQLException(msg);
00291 }
00292 }
00293 notifySuccess();
00294 }
00295
00296
00297
00298
00299
00300
00301 public ControllerResultSet getResult()
00302 {
00303 return result;
00304 }
00305
00306
00307
00308
00309 public String toString()
00310 {
00311 return "ReadStoredProcedureTask (" + proc.getSQL() + ")";
00312 }
00313 }