KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > loadbalancer > tasks > SelectRequestTask


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Julie Marguerite, Jaco Swart.
23  */

24
25 package org.objectweb.cjdbc.controller.loadbalancer.tasks;
26
27 import java.sql.Connection JavaDoc;
28 import java.sql.SQLException JavaDoc;
29
30 import org.objectweb.cjdbc.common.exceptions.NoTransactionStartWhenDisablingException;
31 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException;
32 import org.objectweb.cjdbc.common.log.Trace;
33 import org.objectweb.cjdbc.common.sql.SelectRequest;
34 import org.objectweb.cjdbc.common.util.Constants;
35 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
36 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager;
37 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer;
38 import org.objectweb.cjdbc.controller.loadbalancer.BackendWorkerThread;
39 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
40
41 /**
42  * Executes a <code>SELECT</code> statement.
43  *
44  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
45  * @author <a HREF="mailto:Julie.Marguerite@inria.fr">Julie Marguerite </a>
46  * @author <a HREF="mailto:jaco.swart@iblocks.co.uk">Jaco Swart </a>
47  * @version 1.0
48  */

49 public class SelectRequestTask extends AbstractTask
50 {
51   private SelectRequest request;
52   private ControllerResultSet result;
53
54   /**
55    * Creates a new <code>WriteRequestTask</code> instance.
56    *
57    * @param nbToComplete number of threads that must succeed before returning
58    * @param totalNb total number of threads
59    * @param request an <code>AbstractWriteRequest</code>
60    */

61   public SelectRequestTask(int nbToComplete, int totalNb, SelectRequest request)
62   {
63     super(nbToComplete, totalNb);
64     this.request = request;
65   }
66
67   /**
68    * Executes a write request with the given backend thread
69    *
70    * @param backendThread the backend thread that will execute the task
71    * @throws SQLException if an error occurs
72    */

73   public void executeTask(BackendWorkerThread backendThread)
74       throws SQLException JavaDoc
75   {
76     DatabaseBackend backend = backendThread.getBackend();
77
78     AbstractConnectionManager cm = backend.getConnectionManager(request
79         .getLogin());
80     if (cm == null)
81     {
82       SQLException JavaDoc se = new SQLException JavaDoc(
83           "No Connection Manager for Virtual Login:" + request.getLogin());
84       try
85       {
86         notifyFailure(backendThread, 1, se);
87       }
88       catch (SQLException JavaDoc ignore)
89       {
90
91       }
92       throw se;
93     }
94
95     Trace logger = backendThread.getLogger();
96     if (request.isAutoCommit())
97     { // Use a connection just for this request
98
Connection JavaDoc c = null;
99       try
100       {
101         c = cm.getConnection();
102       }
103       catch (UnreachableBackendException e1)
104       {
105         SQLException JavaDoc se = new SQLException JavaDoc("Backend " + backend.getName()
106             + " is no more reachable.");
107         try
108         {
109           notifyFailure(backendThread, 1, se);
110         }
111         catch (SQLException JavaDoc ignore)
112         {
113         }
114         // Disable this backend (it is no more in sync) by killing the backend
115
// thread
116
backendThread.kill();
117         logger.error("Disabling backend " + backend.getName()
118             + " because it is no more reachable.");
119         throw se;
120       }
121
122       // Sanity check
123
if (c == null)
124       {
125         SQLException JavaDoc se = new SQLException JavaDoc("No more connections");
126         try
127         { // All backends failed, just ignore
128
if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
129               se))
130             return;
131         }
132         catch (SQLException JavaDoc ignore)
133         {
134         }
135         // Disable this backend (it is no more in sync) by killing the backend
136
// thread
137
backendThread.kill();
138         throw new SQLException JavaDoc("Request '"
139             + request.getSQLShortForm(Constants.SQL_SHORT_FORM_LENGTH)
140             + "' failed on backend " + backend.getName() + " (" + se + ")");
141       }
142
143       // Execute Query
144
try
145       {
146         result = AbstractLoadBalancer.executeSelectRequestOnBackend(request,
147             backend, c, null);
148       }
149       catch (Exception JavaDoc e)
150       {
151         try
152         { // All backends failed, just ignore
153
if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
154               e))
155             return;
156         }
157         catch (SQLException JavaDoc ignore)
158         {
159         }
160         throw new SQLException JavaDoc("Request '"
161             + request.getSQLShortForm(Constants.SQL_SHORT_FORM_LENGTH)
162             + "' failed on backend " + backend.getName() + " (" + e + ")");
163       }
164       finally
165       {
166         cm.releaseConnection(c);
167       }
168     }
169     else
170     {
171       Connection JavaDoc c;
172       long tid = request.getTransactionId();
173       Long JavaDoc lTid = new Long JavaDoc(tid);
174
175       try
176       {
177         c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(lTid, cm,
178             request.getTransactionIsolation());
179       }
180       catch (UnreachableBackendException ube)
181       {
182         SQLException JavaDoc se = new SQLException JavaDoc("Backend " + backend.getName()
183             + " is no more reachable.");
184         try
185         {
186           notifyFailure(backendThread, 1, se);
187         }
188         catch (SQLException JavaDoc ignore)
189         {
190         }
191         // Disable this backend (it is no more in sync) by killing the backend
192
// thread
193
backendThread.kill();
194         logger.error("Disabling backend " + backend.getName()
195             + " because it is no more reachable.");
196         throw se;
197       }
198       catch (NoTransactionStartWhenDisablingException e)
199       {
200         logger
201             .error("Disabling backend "
202                 + backend.getName()
203                 + " has been assigned a select request but it cannot start a new transaction for it.");
204         notifyFailure(backendThread, (long) request.getTimeout() * 1000, e);
205         return;
206       }
207       catch (SQLException JavaDoc e1)
208       {
209         SQLException JavaDoc se = new SQLException JavaDoc(
210             "Unable to get connection for transaction " + tid);
211         try
212         { // All backends failed, just ignore
213
if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
214               se))
215             return;
216         }
217         catch (SQLException JavaDoc ignore)
218         {
219         }
220         // Disable this backend (it is no more in sync) by killing the
221
// backend thread
222
backendThread.kill();
223         String JavaDoc msg = "Request '"
224             + request.getSQLShortForm(backend.getSQLShortFormLength())
225             + "' failed on backend " + backend.getName() + " but "
226             + getSuccess() + " succeeded (" + se + ")";
227         logger.error(msg);
228         throw new SQLException JavaDoc(msg);
229       }
230
231       // Sanity check
232
if (c == null)
233       { // Bad connection
234
SQLException JavaDoc se = new SQLException JavaDoc(
235             "Unable to retrieve connection for transaction " + tid);
236         try
237         { // All backends failed, just ignore
238
if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
239               se))
240             return;
241         }
242         catch (SQLException JavaDoc ignore)
243         {
244         }
245         // Disable this backend (it is no more in sync) by killing the
246
// backend thread
247
backendThread.kill();
248         String JavaDoc msg = "Request '"
249             + request.getSQLShortForm(backend.getSQLShortFormLength())
250             + "' failed on backend " + backend.getName() + " but "
251             + getSuccess() + " succeeded (" + se + ")";
252         logger.error(msg);
253         throw new SQLException JavaDoc(msg);
254       }
255
256       // Execute Query
257
try
258       {
259         result = AbstractLoadBalancer.executeSelectRequestOnBackend(request,
260             backend, c, null);
261       }
262       catch (Exception JavaDoc e)
263       {
264         try
265         { // All backends failed, just ignore
266
if (!notifyFailure(backendThread, (long) request.getTimeout() * 1000,
267               e))
268             return;
269         }
270         catch (SQLException JavaDoc ignore)
271         {
272         }
273         throw new SQLException JavaDoc("Request '"
274             + request.getSQLShortForm(Constants.SQL_SHORT_FORM_LENGTH)
275             + "' failed on backend " + backend.getName() + " (" + e + ")");
276       }
277     }
278     notifySuccess();
279   }
280
281   /**
282    * Returns the result.
283    *
284    * @return a <code>ResultSet</code>
285    */

286   public ControllerResultSet getResult()
287   {
288     return result;
289   }
290
291   /**
292    * @see java.lang.Object#toString()
293    */

294   public String JavaDoc toString()
295   {
296     return "SelectRequestTask (" + request.getSQL() + ")";
297   }
298 }
Popular Tags