KickJava   Java API By Example, From Geeks To Geeks.

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


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): ______________________.
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.UnreachableBackendException;
31 import org.objectweb.cjdbc.common.log.Trace;
32 import org.objectweb.cjdbc.common.sql.StoredProcedure;
33 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
34 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager;
35 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer;
36 import org.objectweb.cjdbc.controller.loadbalancer.BackendWorkerThread;
37
38 /**
39  * Executes a write <code>StoredProcedure</code> call.
40  *
41  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
42  * @version 1.0
43  */

44 public class WriteStoredProcedureTask extends AbstractTask
45 {
46   private StoredProcedure proc;
47   private int result;
48
49   /**
50    * Creates a new <code>WriteStoredProcedureTask</code>.
51    *
52    * @param nbToComplete number of threads that must succeed before returning
53    * @param totalNb total number of threads
54    * @param proc the <code>StoredProcedure</code> to call
55    */

56   public WriteStoredProcedureTask(int nbToComplete, int totalNb,
57       StoredProcedure proc)
58   {
59     super(nbToComplete, totalNb);
60     this.proc = proc;
61   }
62
63   /**
64    * Executes a write request with the given backend thread.
65    *
66    * @param backendThread the backend thread that will execute the task
67    * @throws SQLException if an error occurs
68    */

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

297   public int getResult()
298   {
299     return result;
300   }
301
302   /**
303    * @see java.lang.Object#toString()
304    */

305   public String JavaDoc toString()
306   {
307     if (proc.isAutoCommit())
308       return "Write autocommit StoredProcedureTask (" + proc.getSQL() + ")";
309     else
310       return "Write StoredProcedureTask for transaction:"
311           + proc.getTransactionId() + "(" + proc.getSQL() + ")";
312   }
313
314 }
Popular Tags