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