KickJava   Java API By Example, From Geeks To Geeks.

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


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 commit.
40  *
41  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
42  * @version 1.0
43  */

44 public class Commit extends DistributedTransactionMarker
45 {
46   private static final long serialVersionUID = 1222810057093662283L;
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 commits 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>Commit</code> message.
59    *
60    * @param login login that commit the transaction
61    * @param transactionId id of the transaction to commit
62    */

63   public Commit(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().commit(tm);
94     }
95     catch (SQLException JavaDoc e)
96     {
97       drm.getLogger().warn(
98           Translate.get("virtualdatabase.distributed.commit.sqlexception"), e);
99       throw e;
100     }
101     catch (RuntimeException JavaDoc re)
102     {
103       drm.getLogger().warn(
104           Translate.get("virtualdatabase.distributed.commit.exception"), re);
105       throw new SQLException JavaDoc(re.getMessage());
106     }
107   }
108
109   /**
110    * Execution of a distributed commit command on the specified
111    * <code>DistributedRequestManager</code>
112    *
113    * @param drm the DistributedRequestManager that will execute the commit
114    * @return Boolean.TRUE if everything went fine or a SQLException if an error
115    * occured
116    * @throws SQLException if an error occurs
117    */

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

206   public String JavaDoc toString()
207   {
208     return "Commit transaction " + transactionId;
209   }
210 }
Popular Tags