KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > virtualdatabase > protocol > DistributedRollback


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  * Copyright (C) 2005-2006 Continuent, Inc.
7  * Contact: sequoia@continuent.org
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): ______________________.
23  */

24
25 package org.continuent.sequoia.controller.virtualdatabase.protocol;
26
27 import java.io.Serializable JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.util.LinkedList JavaDoc;
30
31 import org.continuent.sequoia.common.exceptions.NoMoreBackendException;
32 import org.continuent.sequoia.common.i18n.Translate;
33 import org.continuent.sequoia.common.log.Trace;
34 import org.continuent.sequoia.controller.loadbalancer.AllBackendsFailedException;
35 import org.continuent.sequoia.controller.requestmanager.TransactionMetaData;
36 import org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager;
37 import org.continuent.sequoia.controller.requests.AbstractRequest;
38 import org.continuent.sequoia.controller.requests.UnknownWriteRequest;
39
40 /**
41  * Execute a distributed rollback.
42  *
43  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
44  * @version 1.0
45  */

46 public class DistributedRollback extends DistributedTransactionMarker
47 {
48   private static final long serialVersionUID = -8954391235872189513L;
49
50   // Login that rollbacks the transaction. This is used in case the remote
51
// controller has to log the commit but didn't see the begin in which case it
52
// will not be able to retrieve the transaction marker metadata
53
private String JavaDoc login;
54
55   /**
56    * Creates a new <code>Rollback</code> message.
57    *
58    * @param login login that rollback the transaction
59    * @param transactionId id of the transaction to commit
60    */

61   public DistributedRollback(String JavaDoc login, long transactionId)
62   {
63     super(transactionId);
64     this.login = login;
65   }
66
67   /**
68    * @see org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedTransactionMarker#scheduleCommand(org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager)
69    */

70   public Object JavaDoc scheduleCommand(DistributedRequestManager drm)
71       throws SQLException JavaDoc
72   {
73     LinkedList JavaDoc totalOrderQueue = drm.getVirtualDatabase().getTotalOrderQueue();
74     if (totalOrderQueue != null)
75     {
76       synchronized (totalOrderQueue)
77       {
78         totalOrderQueue.addLast(this);
79       }
80     }
81     return this;
82   }
83
84   /**
85    * Execution of a distributed rollback command on the specified
86    * <code>DistributedRequestManager</code>
87    *
88    * @param drm the DistributedRequestManager that will execute the rollback
89    * @return Boolean.TRUE if everything went fine or a SQLException if an error
90    * occured
91    * @throws SQLException if an error occurs
92    */

93   public Serializable JavaDoc executeCommand(DistributedRequestManager drm)
94       throws SQLException JavaDoc
95   {
96     boolean hasBeenScheduled = false;
97     boolean transactionStartedOnThisController = true;
98     Long JavaDoc tid = new Long JavaDoc(transactionId);
99     TransactionMetaData tm;
100     try
101     {
102       tm = drm.getTransactionMetaData(tid);
103     }
104     catch (SQLException JavaDoc ignore)
105     {
106       // The transaction was started before the controller joined the
107
// cluster, build a fake tm so that we will be able to log it.
108
transactionStartedOnThisController = false;
109       tm = new TransactionMetaData(transactionId, 0, login, false, 0);
110     }
111
112     Trace logger = drm.getLogger();
113     try
114     {
115       if (transactionStartedOnThisController)
116       {
117         drm.getScheduler().rollback(tm, this);
118         hasBeenScheduled = true;
119       }
120
121       if (logger.isDebugEnabled())
122         logger
123             .debug(Translate.get("transaction.rollback", String.valueOf(tid)));
124
125       // Send to load balancer
126
drm.getLoadBalancer().rollback(tm);
127
128       // Update recovery log
129
drm.getRecoveryLog().logRequestCompletion(tm.getLogId(), true, 0);
130
131       // Invalidate the query result cache if this transaction has updated the
132
// cache or altered the schema
133
if ((drm.getResultCache() != null)
134           && (tm.altersQueryResultCache() || tm.altersDatabaseSchema()))
135         drm.getResultCache().rollback(tm.getTransactionId());
136
137       // Check for schema modifications that need to be rollbacked
138
if (tm.altersDatabaseSchema())
139       {
140         if (drm.getMetadataCache() != null)
141           drm.getMetadataCache().flushCache();
142         drm.setSchemaIsDirty(true);
143       }
144
145       // Notify scheduler for completion
146
if (hasBeenScheduled)
147         drm.getScheduler().rollbackCompleted(tm, true);
148
149       if (transactionStartedOnThisController)
150       {
151         drm.completeTransaction(tid);
152       }
153     }
154     catch (NoMoreBackendException e)
155     {
156       if (logger.isDebugEnabled())
157         logger
158             .debug(Translate.get(
159                 "virtualdatabase.distributed.rollback.logging.only",
160                 transactionId));
161       addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm);
162       throw e;
163     }
164     catch (SQLException JavaDoc e)
165     {
166       if (tm.isReadOnly())
167       {
168         if (logger.isWarnEnabled())
169         {
170           logger
171               .warn("Ignoring failure of rollback for read-only transaction, exception was: "
172                   + e);
173         }
174
175         if (hasBeenScheduled)
176           drm.getScheduler().rollbackCompleted(tm, true);
177
178         return Boolean.TRUE;
179       }
180
181       addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm);
182       logger.warn(Translate
183           .get("virtualdatabase.distributed.rollback.sqlexception"), e);
184       return e;
185     }
186     catch (RuntimeException JavaDoc re)
187     {
188       addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm);
189       logger.warn(Translate
190           .get("virtualdatabase.distributed.rollback.exception"), re);
191       throw new SQLException JavaDoc(re.getMessage());
192     }
193     catch (AllBackendsFailedException e)
194     {
195       addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm);
196       if (logger.isDebugEnabled())
197         logger.debug(Translate.get(
198             "virtualdatabase.distributed.commit.all.backends.locally.failed",
199             transactionId));
200       return e;
201     }
202     return Boolean.TRUE;
203   }
204
205   private void addRollbackFailureOnAllBackends(DistributedRequestManager drm,
206       boolean hasBeenScheduled, TransactionMetaData tm)
207   {
208     AbstractRequest request = new UnknownWriteRequest("rollback", false, 0,
209         "\n");
210     request.setTransactionId(transactionId);
211     request.setLogId(tm.getLogId());
212     drm.addFailedOnAllBackends(request, hasBeenScheduled);
213   }
214
215   /**
216    * @see java.lang.Object#toString()
217    */

218   public String JavaDoc toString()
219   {
220     return "Rollback transaction " + transactionId;
221   }
222 }
Popular Tags