KickJava   Java API By Example, From Geeks To Geeks.

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


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

22
23 package org.continuent.sequoia.controller.loadbalancer.tasks;
24
25 import java.sql.Connection JavaDoc;
26 import java.sql.SQLException JavaDoc;
27
28 import org.continuent.sequoia.common.i18n.Translate;
29 import org.continuent.sequoia.common.log.Trace;
30 import org.continuent.sequoia.controller.backend.DatabaseBackend;
31 import org.continuent.sequoia.controller.connection.AbstractConnectionManager;
32 import org.continuent.sequoia.controller.connection.PooledConnection;
33 import org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread;
34 import org.continuent.sequoia.controller.requestmanager.TransactionMetaData;
35 import org.continuent.sequoia.controller.requests.AbstractRequest;
36 import org.continuent.sequoia.controller.requests.UnknownWriteRequest;
37
38 /**
39  * Task to rollback a transaction.
40  *
41  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
42  * @author <a HREF="mailto:Julie.Marguerite@inria.fr">Julie Marguerite </a>
43  * @version 1.0
44  */

45 public class RollbackTask extends AbstractTask
46 {
47   // Transaction metadata (login, transaction id, timeout)
48
private TransactionMetaData tm;
49
50   static Trace endUserLogger = Trace
51                                                 .getLogger("org.continuent.sequoia.enduser");
52
53   /**
54    * Commits a transaction given a login and a transaction id.
55    *
56    * @param nbToComplete number of threads that must succeed before returning
57    * @param totalNb total number of threads
58    * @param tm transaction metadata
59    * @throws NullPointerException if tm is null
60    */

61   public RollbackTask(int nbToComplete, int totalNb, TransactionMetaData tm)
62       throws NullPointerException JavaDoc
63   {
64     super(nbToComplete, totalNb, tm.isPersistentConnection(), tm
65         .getPersistentConnectionId());
66     if (tm == null)
67       throw new NullPointerException JavaDoc("Unexpected null metadata in RollbackTask");
68     this.tm = tm;
69   }
70
71   /**
72    * Rollbacks a transaction with the given backend thread.
73    *
74    * @param backendThread the backend thread that will execute the task
75    * @throws SQLException if an error occurs
76    */

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

181   public AbstractRequest getRequest()
182   {
183     return null;
184   }
185
186   /**
187    * @see org.continuent.sequoia.controller.loadbalancer.tasks.AbstractTask#getTransactionId()
188    */

189   public long getTransactionId()
190   {
191     return tm.getTransactionId();
192   }
193
194   /**
195    * @see org.continuent.sequoia.controller.loadbalancer.tasks.AbstractTask#isAutoCommit()
196    */

197   public boolean isAutoCommit()
198   {
199     return false;
200   }
201
202   /**
203    * @see java.lang.Object#equals(java.lang.Object)
204    */

205   public boolean equals(Object JavaDoc other)
206   {
207     if ((other == null) || !(other instanceof RollbackTask))
208       return false;
209
210     RollbackTask rollback = (RollbackTask) other;
211     return this.getTransactionId() == rollback.getTransactionId();
212   }
213
214   /**
215    * Returns the transaction metadata value.
216    *
217    * @return Returns the tm.
218    */

219   public final TransactionMetaData getTransactionMetaData()
220   {
221     return tm;
222   }
223
224   /**
225    * @see java.lang.Object#hashCode()
226    */

227   public int hashCode()
228   {
229     return (int) this.getTransactionId();
230   }
231
232   /**
233    * @see java.lang.Object#toString()
234    */

235   public String JavaDoc toString()
236   {
237     return "RollbackTask (" + tm.getTransactionId() + ")";
238   }
239 }
Popular Tags