KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > loadbalancer > tasks > SavepointTask


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
6  * Contact: sequoia@continuent.org
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * Initial developer(s): Jean-Bernard van Zuylen.
21  * Contributor(s): ______________________.
22  */

23
24 package org.continuent.sequoia.controller.loadbalancer.tasks;
25
26 import java.sql.Connection JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import java.sql.Savepoint JavaDoc;
29
30 import org.continuent.sequoia.common.i18n.Translate;
31 import org.continuent.sequoia.common.log.Trace;
32 import org.continuent.sequoia.controller.backend.DatabaseBackend;
33 import org.continuent.sequoia.controller.connection.AbstractConnectionManager;
34 import org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread;
35 import org.continuent.sequoia.controller.requestmanager.TransactionMetaData;
36 import org.continuent.sequoia.controller.requests.AbstractRequest;
37 import org.continuent.sequoia.controller.requests.UnknownWriteRequest;
38
39 /**
40  * Task to set a savepoint to a transaction.
41  *
42  * @author <a HREF="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen
43  * </a>
44  * @version 1.0
45  */

46 public class SavepointTask extends AbstractTask
47 {
48   /** Transaction metadata (login, transaction id, timeout) */
49   private TransactionMetaData tm;
50   /** Name of the savepoint. */
51   private String JavaDoc savepointName;
52   /** Savepoint that was created. */
53   private Savepoint JavaDoc result;
54
55   static Trace endUserLogger = Trace
56                                                 .getLogger("org.continuent.sequoia.enduser");
57
58   /**
59    * Sets a savepoint given a transaction metadata and a savepoint name.
60    *
61    * @param nbToComplete number of threads that must succeed before returning
62    * @param totalNb total number of threads
63    * @param tm transaction metadata
64    * @param savepointName the savepoint to remove
65    * @throws NullPointerException if tm is null
66    */

67   public SavepointTask(int nbToComplete, int totalNb, TransactionMetaData tm,
68       String JavaDoc savepointName) throws NullPointerException JavaDoc
69   {
70     super(nbToComplete, totalNb, tm.isPersistentConnection(), tm
71         .getPersistentConnectionId());
72     if (tm == null)
73       throw new NullPointerException JavaDoc("Unexpected null metadata in BeginTask");
74     this.tm = tm;
75     this.savepointName = savepointName;
76   }
77
78   /**
79    * @see org.continuent.sequoia.controller.loadbalancer.tasks.AbstractTask#executeTask(org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread)
80    */

81   public void executeTask(BackendWorkerThread backendThread)
82       throws SQLException JavaDoc
83   {
84     DatabaseBackend backend = backendThread.getBackend();
85     Long JavaDoc lTid = new Long JavaDoc(tm.getTransactionId());
86
87     AbstractConnectionManager cm = backend.getConnectionManager(tm.getLogin());
88     if (cm == null)
89     {
90       SQLException JavaDoc se = new SQLException JavaDoc(
91           "No Connection Manager for Virtual Login:" + tm.getLogin());
92       try
93       {
94         notifyFailure(backendThread, -1, se);
95       }
96       catch (SQLException JavaDoc ignore)
97       {
98
99       }
100       throw se;
101     }
102
103     Savepoint JavaDoc savepoint = null;
104     try
105     {
106       AbstractRequest fakeRequest = new UnknownWriteRequest("savepoint "
107           + savepointName, false, 0, "\n");
108       fakeRequest.setTransactionId(tm.getTransactionId());
109       // Set transaction isolation level in case the transaction was not started
110
// yet
111
fakeRequest
112           .setTransactionIsolation(org.continuent.sequoia.driver.Connection.DEFAULT_TRANSACTION_ISOLATION_LEVEL);
113       Connection JavaDoc c = backend.getConnectionForTransactionAndLazyBeginIfNeeded(
114           fakeRequest, cm);
115
116       // Sanity check
117
if (c == null)
118       { // Bad connection
119
backend.stopTransaction(lTid);
120         SQLException JavaDoc se = new SQLException JavaDoc(
121             "Unable to retrieve connection for transaction "
122                 + tm.getTransactionId());
123
124         try
125         { // All backends failed, just ignore
126
if (!notifyFailure(backendThread, tm.getTimeout(), se))
127             return;
128         }
129         catch (SQLException JavaDoc ignore)
130         {
131         }
132         // Disable this backend (it is no more in sync) by killing the backend
133
// thread
134
backendThread.getLoadBalancer().disableBackend(backend, true);
135         String JavaDoc msg = "Failed to set savepoint for transaction "
136             + tm.getTransactionId() + " on backend " + backend.getName()
137             + " but " + getSuccess() + " succeeded (" + se + ")";
138         backendThread.getLogger().error(msg);
139         endUserLogger.error(Translate.get("loadbalancer.backend.disabling",
140             backend.getName()));
141         throw new SQLException JavaDoc(msg);
142       }
143
144       // Execute Query
145
savepoint = c.setSavepoint(savepointName);
146       result = savepoint;
147     }
148     catch (Exception JavaDoc e)
149     {
150       try
151       {
152         if (!notifyFailure(backendThread, tm.getTimeout(), new SQLException JavaDoc(e
153             .getMessage())))
154           return;
155       }
156       catch (SQLException JavaDoc ignore)
157       {
158       }
159       // Disable this backend (it is no more in sync) by killing the backend
160
// thread
161
backendThread.getLoadBalancer().disableBackend(backend, true);
162       String JavaDoc msg = "Failed to set savepoint for transaction "
163           + tm.getTransactionId() + " on backend " + backend.getName()
164           + " but " + getSuccess() + " succeeded (" + e + ")";
165       backendThread.getLogger().error(msg);
166       endUserLogger.error(Translate.get("loadbalancer.backend.disabling",
167           backend.getName()));
168       throw new SQLException JavaDoc(msg);
169     }
170     finally
171     {
172       if (savepoint != null)
173         backend.addSavepoint(lTid, savepoint);
174     }
175
176     notifySuccess(backendThread);
177   }
178
179   /**
180    * @see org.continuent.sequoia.controller.loadbalancer.tasks.AbstractTask#getRequest()
181    */

182   public AbstractRequest getRequest()
183   {
184     return null;
185   }
186
187   /**
188    * Returns the result.
189    *
190    * @return Savepoint
191    */

192   public Savepoint JavaDoc getResult()
193   {
194     return result;
195   }
196
197   /**
198    * @return savepoint name
199    */

200   public String JavaDoc getSavepointName()
201   {
202     return savepointName;
203   }
204
205   /**
206    * @see org.continuent.sequoia.controller.loadbalancer.tasks.AbstractTask#getTransactionId()
207    */

208   public long getTransactionId()
209   {
210     return tm.getTransactionId();
211   }
212
213   /**
214    * @see org.continuent.sequoia.controller.loadbalancer.tasks.AbstractTask#isAutoCommit()
215    */

216   public boolean isAutoCommit()
217   {
218     return false;
219   }
220
221   /**
222    * @see java.lang.Object#equals(java.lang.Object)
223    */

224   public boolean equals(Object JavaDoc other)
225   {
226     if ((other == null) || !(other instanceof SavepointTask))
227       return false;
228
229     SavepointTask savepoint = (SavepointTask) other;
230     return (this.getTransactionId() == savepoint.getTransactionId())
231         && (this.savepointName.equals(savepoint.getSavepointName()));
232   }
233
234   /**
235    * @see java.lang.Object#hashCode()
236    */

237   public int hashCode()
238   {
239     return (int) this.getTransactionId();
240   }
241
242   /**
243    * @see java.lang.Object#toString()
244    */

245   public String JavaDoc toString()
246   {
247     return "SavepointTask for transaction " + tm.getTransactionId() + " ("
248         + savepointName + ")";
249   }
250
251 }
252
Popular Tags