KickJava   Java API By Example, From Geeks To Geeks.

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


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.
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.controller.backend.DatabaseBackend;
34 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager;
35 import org.objectweb.cjdbc.controller.loadbalancer.BackendWorkerThread;
36
37 /**
38  * Task to begin a transaction. Note that this task does not properly set the
39  * transaction isolation but this is not a real issue since it is meant to be
40  * used by the recovery log that does not execute reads and provide its own
41  * serial order.
42  *
43  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
44  * @author <a HREF="mailto:Julie.Marguerite@inria.fr">Julie Marguerite </a>
45  * @version 1.0
46  */

47 public class BeginTask extends AbstractTask
48 {
49   /** Login used by the connection. */
50   private String JavaDoc login;
51
52   /** Unique transaction identifier. */
53   private long transactionId;
54
55   /** Request timeout in milliseconds. */
56   private long timeout;
57
58   /**
59    * Begins a new transaction given a login and a transaction id.
60    *
61    * @param nbToComplete number of threads that must succeed before returning
62    * @param totalNb total number of threads
63    * @param timeout request timeout in milliseconds
64    * @param login the login used by the connection
65    * @param transactionId a unique transaction identifier
66    */

67   public BeginTask(int nbToComplete, int totalNb, long timeout, String JavaDoc login,
68       long transactionId)
69   {
70     super(nbToComplete, totalNb);
71     this.login = login;
72     this.transactionId = transactionId;
73     this.timeout = timeout;
74   }
75
76   /**
77    * Begins a new transaction with the given backend thread.
78    *
79    * @param backendThread the backend thread that will execute the task
80    * @exception SQLException if an error occurs
81    */

82   public void executeTask(BackendWorkerThread backendThread)
83       throws SQLException JavaDoc
84   {
85     DatabaseBackend backend = backendThread.getBackend();
86     if (backend.isDisabling())
87     {
88       // Backend is disabling, we do not execute queries except the one in the
89
// transaction we already started. Just notify the completion for the
90
// others.
91
notifyCompletion();
92       return;
93     }
94
95     try
96     {
97       AbstractConnectionManager cm = backend.getConnectionManager(login);
98       if (cm == null)
99       {
100         SQLException JavaDoc se = new SQLException JavaDoc(
101             "No Connection Manager for Virtual Login:" + login);
102         try
103         {
104           notifyFailure(backendThread, 1, se);
105         }
106         catch (SQLException JavaDoc ignore)
107         {
108
109         }
110         throw se;
111       }
112
113       Connection JavaDoc c;
114       Long JavaDoc lTid = new Long JavaDoc(transactionId);
115       Trace logger = backendThread.getLogger();
116
117       try
118       {
119         c = backend
120             .getConnectionForTransactionAndLazyBeginIfNeeded(
121                 lTid,
122                 cm,
123                 org.objectweb.cjdbc.driver.Connection.DEFAULT_TRANSACTION_ISOLATION_LEVEL);
124       }
125       catch (UnreachableBackendException ube)
126       {
127         SQLException JavaDoc se = new SQLException JavaDoc("Backend " + backend.getName()
128             + " is no more reachable.");
129         try
130         {
131           notifyFailure(backendThread, 1, se);
132         }
133         catch (SQLException JavaDoc ignore)
134         {
135         }
136         // Disable this backend (it is no more in sync) by killing the backend
137
// thread
138
backendThread.kill();
139         logger.error("Disabling backend " + backend.getName()
140             + " because it is no more reachable.");
141         throw se;
142       }
143       catch (NoTransactionStartWhenDisablingException e)
144       {
145         // Backend is disabling, we do not execute queries except the one in the
146
// transaction we already started. Just notify the completion for the
147
// others.
148
notifyCompletion();
149         return;
150       }
151       catch (SQLException JavaDoc e1)
152       {
153         SQLException JavaDoc se = new SQLException JavaDoc(
154             "Unable to get connection for transaction " + lTid);
155         try
156         { // All backends failed, just ignore
157
if (!notifyFailure(backendThread, timeout * 1000, se))
158             return;
159         }
160         catch (SQLException JavaDoc ignore)
161         {
162         }
163         // Disable this backend (it is no more in sync) by killing the
164
// backend thread
165
backendThread.kill();
166         String JavaDoc msg = "Begin of transaction " + transactionId
167             + " failed on backend " + backend.getName() + " but "
168             + getSuccess() + " succeeded (" + se + ")";
169         logger.error(msg);
170         throw new SQLException JavaDoc(msg);
171       }
172
173       // Sanity check
174
if (c == null)
175       { // Bad connection
176
SQLException JavaDoc se = new SQLException JavaDoc(
177             "No more connection to start a new transaction.");
178         try
179         { // All backends failed, just ignore
180
if (!notifyFailure(backendThread, timeout, se))
181             return;
182         }
183         catch (SQLException JavaDoc ignore)
184         {
185         }
186       }
187       else
188       {
189         notifyCompletion();
190       }
191     }
192     catch (Exception JavaDoc e)
193     {
194       try
195       {
196         if (!notifyFailure(backendThread, timeout, new SQLException JavaDoc(e
197             .getMessage())))
198           return;
199       }
200       catch (SQLException JavaDoc ignore)
201       {
202       }
203       String JavaDoc msg = "Failed to begin transaction " + transactionId
204           + " on backend " + backend.getName() + " (" + e + ")";
205       backendThread.getLogger().error(msg);
206       throw new SQLException JavaDoc(msg);
207     }
208   }
209
210   /**
211    * @see java.lang.Object#toString()
212    */

213   public String JavaDoc toString()
214   {
215     return "BeginTask (" + transactionId + ")";
216   }
217 }
Popular Tags