KickJava   Java API By Example, From Geeks To Geeks.

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


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.connection.PooledConnection;
35 import org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread;
36 import org.continuent.sequoia.controller.requestmanager.TransactionMetaData;
37 import org.continuent.sequoia.controller.requests.AbstractRequest;
38 import org.continuent.sequoia.controller.requests.UnknownWriteRequest;
39
40 /**
41  * This class defines a RollbackToSavepointTask
42  *
43  * @author <a HREF="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen
44  * </a>
45  * @version 1.0
46  */

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

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

80   public void executeTask(BackendWorkerThread backendThread)
81       throws SQLException JavaDoc
82   {
83     DatabaseBackend backend = backendThread.getBackend();
84     Long JavaDoc lTid = new Long JavaDoc(tm.getTransactionId());
85
86     AbstractConnectionManager cm = backend.getConnectionManager(tm.getLogin());
87     if (cm == null)
88     {
89       SQLException JavaDoc se = new SQLException JavaDoc(
90           "No Connection Manager for Virtual Login:" + tm.getLogin());
91       try
92       {
93         notifyFailure(backendThread, -1, se);
94       }
95       catch (SQLException JavaDoc ignore)
96       {
97
98       }
99       throw se;
100     }
101
102     PooledConnection pc = cm.retrieveConnectionForTransaction(tm
103         .getTransactionId());
104
105     // Sanity check
106
if (pc == null)
107     { // Bad connection
108
backend.stopTransaction(lTid);
109       SQLException JavaDoc se = new SQLException JavaDoc(
110           "Unable to retrieve connection for transaction "
111               + tm.getTransactionId());
112       try
113       { // All backends failed, just ignore
114
if (!notifyFailure(backendThread, tm.getTimeout(), se))
115           return;
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.getLoadBalancer().disableBackend(backend, true);
123       String JavaDoc msg = "Failed to rollback transaction " + tm.getTransactionId()
124           + " to savepoint " + savepointName + " on backend "
125           + backend.getName() + " but " + getSuccess() + " succeeded (" + se
126           + ")";
127       backendThread.getLogger().error(msg);
128       endUserLogger.error(Translate.get("loadbalancer.backend.disabling",
129           backend.getName()));
130       throw new SQLException JavaDoc(msg);
131     }
132
133     // Execute Query
134
try
135     {
136       Savepoint JavaDoc savepoint = backend.getSavepoint(lTid, savepointName);
137       if (savepoint != null)
138       {
139         Connection JavaDoc c = pc.getConnection();
140         c.rollback(savepoint);
141       }
142       else
143       {
144         String JavaDoc msg = "No savepoint named " + savepointName
145             + " was found cannot rollback to savepoint in transaction " + lTid;
146         backend.getLogger().warn(msg);
147         throw new SQLException JavaDoc(msg);
148       }
149
150       if (tm.altersDatabaseSchema())
151       { // Flag the schema as dirty in case the transaction contained DDL
152
UnknownWriteRequest fakeRequest = new UnknownWriteRequest("rollback "
153             + savepointName, false, 0, null);
154         fakeRequest.setLogin(tm.getLogin());
155         fakeRequest.setIsAutoCommit(false);
156         fakeRequest.setTransactionId(getTransactionId());
157         fakeRequest.setPersistentConnection(isPersistentConnection());
158         fakeRequest.setPersistentConnectionId(getPersistentConnectionId());
159         backendThread.getBackend().setSchemaIsDirty(true, fakeRequest);
160       }
161     }
162     catch (Exception JavaDoc e)
163     {
164       try
165       {
166         if (!notifyFailure(backendThread, tm.getTimeout(), new SQLException JavaDoc(e
167             .getMessage()).initCause(e)))
168           return;
169       }
170       catch (SQLException JavaDoc ignore)
171       {
172       }
173       // Disable this backend (it is no more in sync) by killing the backend
174
// thread
175
backendThread.getLoadBalancer().disableBackend(backend, true);
176       String JavaDoc msg = "Failed to rollback transaction " + tm.getTransactionId()
177           + " to savepoint " + savepointName + " on backend "
178           + backend.getName() + " but " + getSuccess() + " succeeded (" + e
179           + ")";
180       backendThread.getLogger().error(msg);
181       endUserLogger.error(Translate.get("loadbalancer.backend.disabling",
182           backend.getName()));
183       throw new SQLException JavaDoc(msg);
184     }
185     notifySuccess(backendThread);
186   }
187
188   /**
189    * @see org.continuent.sequoia.controller.loadbalancer.tasks.AbstractTask#getRequest()
190    */

191   public AbstractRequest getRequest()
192   {
193     return null;
194   }
195
196   /**
197    * @return savepoint name
198    */

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

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

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

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

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

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