KickJava   Java API By Example, From Geeks To Geeks.

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


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

46 public class DistributedCommit extends DistributedTransactionMarker
47 {
48   private static final long serialVersionUID = 1222810057093662283L;
49
50   // Login that commits 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>Commit</code> message.
57    *
58    * @param login login that commit the transaction
59    * @param transactionId id of the transaction to commit
60    */

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

213   public String JavaDoc toString()
214   {
215     return "Commit transaction " + transactionId;
216   }
217 }
Popular Tags