KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > virtualdatabase > protocol > Rollback


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 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): ______________________.
23  */

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

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

63   public Rollback(String JavaDoc login, long transactionId)
64   {
65     super(transactionId);
66     this.login = login;
67   }
68
69   /**
70    * @see org.objectweb.cjdbc.controller.virtualdatabase.protocol.DistributedTransactionMarker#scheduleCommand(org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager)
71    */

72   public void scheduleCommand(DistributedRequestManager drm)
73       throws SQLException JavaDoc
74   {
75     transactionStartedOnThisController = true;
76     tid = new Long JavaDoc(transactionId);
77     try
78     {
79       tm = drm.getTransactionMarker(tid);
80     }
81     catch (SQLException JavaDoc ignore)
82     {
83       // The transaction was started before the controller joined the
84
// cluster, build a fake tm so that we will be able to log it.
85
transactionStartedOnThisController = false;
86       tm = new TransactionMarkerMetaData(transactionId, 0, login);
87       return;
88     }
89
90     try
91     {
92       // Post in the total order queue
93
drm.getScheduler().rollback(tm);
94     }
95     catch (SQLException JavaDoc e)
96     {
97       drm.getLogger()
98           .warn(
99               Translate
100                   .get("virtualdatabase.distributed.rollback.sqlexception"), e);
101       throw e;
102     }
103     catch (RuntimeException JavaDoc re)
104     {
105       drm.getLogger().warn(
106           Translate.get("virtualdatabase.distributed.rollback.exception"), re);
107       throw new SQLException JavaDoc(re.getMessage());
108     }
109   }
110
111   /**
112    * Execution of a distributed rollback command on the specified
113    * <code>DistributedRequestManager</code>
114    *
115    * @param drm the DistributedRequestManager that will execute the rollback
116    * @return Boolean.TRUE if everything went fine or a SQLException if an error
117    * occured
118    * @throws SQLException if an error occurs
119    */

120   public Object JavaDoc executeCommand(DistributedRequestManager drm)
121       throws SQLException JavaDoc
122   {
123     Trace logger = drm.getLogger();
124     numberOfEnabledBackends = drm.getLoadBalancer()
125         .getNumberOfEnabledBackends();
126     try
127     {
128       if (numberOfEnabledBackends == 0)
129         throw new NoMoreBackendException(
130             "No backend enabled on this controller");
131
132       if (logger.isDebugEnabled())
133         logger.debug(Translate.get("transaction.rollback", "" + tid));
134
135       // Send to load balancer
136
drm.getLoadBalancer().rollback(tm);
137
138       // Notify the cache
139
if (drm.getResultCache() != null)
140         drm.getResultCache().rollback(tm.getTransactionId());
141
142       // Notify the recovery log manager
143
if (drm.getRecoveryLog() != null)
144         drm.getRecoveryLog().logRollback(tm);
145     }
146     catch (NoMoreBackendException e)
147     {
148       // Log the query in any case for later recovery (if the request really
149
// failed, it will be unloged later)
150
if (drm.getRecoveryLog() != null)
151       {
152         if (logger.isDebugEnabled())
153           logger.debug(Translate.get(
154               "virtualdatabase.distributed.rollback.logging.only",
155               transactionId));
156
157         if (numberOfEnabledBackends == 0)
158         { // Wait to be sure that we log in the proper order
159
Rollback totalOrderRollback = new Rollback(tm.getLogin(),
160               transactionId);
161           if (drm.getLoadBalancer()
162               .waitForTotalOrder(totalOrderRollback, false))
163             drm.getLoadBalancer().removeHeadFromAndNotifyTotalOrderQueue();
164         }
165         long logId = drm.getRecoveryLog().logRollback(tm);
166         e.setRecoveryLogId(logId);
167         e.setLogin(tm.getLogin());
168       }
169       throw e;
170     }
171     catch (SQLException JavaDoc e)
172     {
173       logger.warn(Translate
174           .get("virtualdatabase.distributed.rollback.sqlexception"), e);
175       return e;
176     }
177     catch (RuntimeException JavaDoc re)
178     {
179       logger.warn(Translate
180           .get("virtualdatabase.distributed.rollback.exception"), re);
181       throw new SQLException JavaDoc(re.getMessage());
182     }
183     catch (AllBackendsFailedException e)
184     {
185       AbstractRequest request = new UnknownRequest("rollback", false, 0, "\n");
186       request.setTransactionId(transactionId);
187       drm.addFailedOnAllBackends(request);
188       if (logger.isDebugEnabled())
189         logger.debug(Translate.get(
190             "virtualdatabase.distributed.commit.all.backends.locally.failed",
191             transactionId));
192       return e;
193     }
194     finally
195     {
196       if (transactionStartedOnThisController)
197       {
198         // Notify scheduler for completion
199
drm.getScheduler().rollbackCompleted(transactionId);
200         drm.completeTransaction(tid);
201       }
202     }
203     return Boolean.TRUE;
204   }
205
206   /**
207    * @see java.lang.Object#toString()
208    */

209   public String JavaDoc toString()
210   {
211     return "Rollback transaction " + transactionId;
212   }
213 }
Popular Tags