KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > requestmanager > distributed > RAIDb2DistributedRequestManager


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): Jean-Bernard van Zuylen, Damian Arregui.
21  */

22
23 package org.continuent.sequoia.controller.requestmanager.distributed;
24
25 import java.io.Serializable JavaDoc;
26 import java.sql.SQLException JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30
31 import javax.management.NotCompliantMBeanException JavaDoc;
32
33 import org.continuent.hedera.adapters.MulticastRequestAdapter;
34 import org.continuent.hedera.adapters.MulticastResponse;
35 import org.continuent.hedera.common.Member;
36 import org.continuent.sequoia.common.exceptions.NoMoreBackendException;
37 import org.continuent.sequoia.common.exceptions.NoResultAvailableException;
38 import org.continuent.sequoia.common.i18n.Translate;
39 import org.continuent.sequoia.controller.backend.result.ControllerResultSet;
40 import org.continuent.sequoia.controller.backend.result.ExecuteResult;
41 import org.continuent.sequoia.controller.backend.result.ExecuteUpdateResult;
42 import org.continuent.sequoia.controller.backend.result.GeneratedKeysResult;
43 import org.continuent.sequoia.controller.cache.result.AbstractResultCache;
44 import org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer;
45 import org.continuent.sequoia.controller.loadbalancer.AllBackendsFailedException;
46 import org.continuent.sequoia.controller.recoverylog.RecoveryLog;
47 import org.continuent.sequoia.controller.requests.AbstractRequest;
48 import org.continuent.sequoia.controller.requests.AbstractWriteRequest;
49 import org.continuent.sequoia.controller.requests.SelectRequest;
50 import org.continuent.sequoia.controller.requests.StoredProcedure;
51 import org.continuent.sequoia.controller.requests.StoredProcedureCallResult;
52 import org.continuent.sequoia.controller.requests.UnknownWriteRequest;
53 import org.continuent.sequoia.controller.scheduler.AbstractScheduler;
54 import org.continuent.sequoia.controller.virtualdatabase.DistributedVirtualDatabase;
55 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedAbort;
56 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecute;
57 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecuteQuery;
58 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecuteUpdate;
59 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCommit;
60 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedReleaseSavepoint;
61 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRequest;
62 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRollback;
63 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRollbackToSavepoint;
64 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedSetSavepoint;
65 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecute;
66 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteQuery;
67 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteUpdate;
68 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteUpdateWithKeys;
69 import org.continuent.sequoia.controller.virtualdatabase.protocol.ExecRemoteStatementExecuteQuery;
70 import org.continuent.sequoia.controller.virtualdatabase.protocol.MessageTimeouts;
71
72 /**
73  * This class defines a RAIDb2DistributedRequestManager
74  *
75  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
76  * @author <a HREF="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen
77  * </a>
78  * @author <a HREF="mailto:Damian.Arregui@emicnetworks.com">Damian Arregui</a>
79  * @version 1.0
80  */

81 public class RAIDb2DistributedRequestManager extends DistributedRequestManager
82 {
83
84   /**
85    * Creates a new <code>RAIDb2DistributedRequestManager</code> instance
86    *
87    * @param vdb the virtual database this request manager belongs to
88    * @param scheduler the Request Scheduler to use
89    * @param cache a Query Cache implementation
90    * @param loadBalancer the Request Load Balancer to use
91    * @param recoveryLog the Log Recovery to use
92    * @param beginTimeout timeout in seconds for begin
93    * @param commitTimeout timeout in seconds for commit
94    * @param rollbackTimeout timeout in seconds for rollback
95    * @throws SQLException if an error occurs
96    * @throws NotCompliantMBeanException if the MBean is not JMX compliant
97    */

98   public RAIDb2DistributedRequestManager(DistributedVirtualDatabase vdb,
99       AbstractScheduler scheduler, AbstractResultCache cache,
100       AbstractLoadBalancer loadBalancer, RecoveryLog recoveryLog,
101       long beginTimeout, long commitTimeout, long rollbackTimeout)
102       throws SQLException JavaDoc, NotCompliantMBeanException JavaDoc
103   {
104     super(vdb, scheduler, cache, loadBalancer, recoveryLog, beginTimeout,
105         commitTimeout, rollbackTimeout);
106   }
107
108   /**
109    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedStatementExecuteQuery(org.continuent.sequoia.controller.requests.SelectRequest)
110    */

111   public ControllerResultSet distributedStatementExecuteQuery(
112       SelectRequest request) throws SQLException JavaDoc
113   {
114     return executeRequestReturningResultSet(request,
115         new DistributedStatementExecuteQuery(request), dvdb
116             .getMessageTimeouts().getExecReadRequestTimeout());
117   }
118
119   /**
120    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#execRemoteStatementExecuteQuery(org.continuent.sequoia.controller.requests.SelectRequest)
121    */

122   public ControllerResultSet execRemoteStatementExecuteQuery(
123       SelectRequest request) throws SQLException JavaDoc
124   {
125     if (dvdb.isProcessMacroBeforeBroadcast())
126       loadBalancer.handleMacros(request);
127     try
128     {
129       // Iterate over controllers in members list (but us) until someone
130
// successfully executes our request.
131
// TODO: We could improve by jumping the controller we know in advance
132
// that they don't have the necessary tables.
133
Iterator JavaDoc i = dvdb.getAllMemberButUs().iterator();
134       SQLException JavaDoc error = null;
135       while (i.hasNext())
136       {
137         Member controller = (Member) i.next();
138         List JavaDoc groupMembers = new ArrayList JavaDoc();
139         groupMembers.add(controller);
140
141         if (logger.isDebugEnabled())
142           logger.debug("Sending request "
143               + request.getSqlShortForm(dvdb.getSqlShortFormLength())
144               + (request.isAutoCommit() ? "" : " transaction "
145                   + request.getTransactionId()) + " to " + controller);
146
147         // Send query to remote controller
148
MulticastResponse responses;
149         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
150             groupMembers,
151             new ExecRemoteStatementExecuteQuery(request),
152             MulticastRequestAdapter.WAIT_ALL,
153             MessageTimeouts.getMinTimeout(dvdb.getMessageTimeouts()
154                 .getExecReadRequestTimeout(), request.getTimeout() * 1000L));
155
156         if (logger.isDebugEnabled())
157           logger.debug("Request "
158               + request.getSqlShortForm(dvdb.getSqlShortFormLength())
159               + " completed.");
160
161         Object JavaDoc ret = responses.getResult(controller);
162         if (ret instanceof ControllerResultSet)
163           return (ControllerResultSet) ret;
164         else if (ret instanceof SQLException JavaDoc)
165           error = (SQLException JavaDoc) ret;
166       }
167
168       if (error == null)
169       {
170         // No one answered, throw
171
throw new NoMoreBackendException();
172       }
173       else
174         throw error;
175     }
176     catch (Exception JavaDoc e)
177     {
178       String JavaDoc msg = "An error occured while executing remote select request "
179           + request.getId();
180       logger.warn(msg, e);
181       if (e instanceof SQLException JavaDoc)
182         throw (SQLException JavaDoc) e;
183       else
184         throw new SQLException JavaDoc(msg + " (" + e + ")");
185     }
186   }
187
188   /**
189    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedStatementExecuteUpdate(org.continuent.sequoia.controller.requests.AbstractWriteRequest)
190    */

191   public ExecuteUpdateResult distributedStatementExecuteUpdate(
192       AbstractWriteRequest request) throws SQLException JavaDoc
193   {
194     return executeRequestReturningInt(request,
195         new DistributedStatementExecuteUpdate(request), dvdb
196             .getMessageTimeouts().getExecWriteRequestTimeout());
197   }
198
199   /**
200    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedStatementExecuteUpdateWithKeys(org.continuent.sequoia.controller.requests.AbstractWriteRequest)
201    */

202   public GeneratedKeysResult distributedStatementExecuteUpdateWithKeys(
203       AbstractWriteRequest request) throws SQLException JavaDoc
204   {
205     return executeRequestReturningGeneratedKeys(request,
206         new DistributedStatementExecuteUpdateWithKeys(request), dvdb
207             .getMessageTimeouts().getExecWriteRequestWithKeysTimeout());
208   }
209
210   /**
211    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedStatementExecute(org.continuent.sequoia.controller.requests.AbstractRequest)
212    */

213   public ExecuteResult distributedStatementExecute(AbstractRequest request)
214       throws SQLException JavaDoc
215   {
216     return executeRequestReturningExecuteResult(request,
217         new DistributedStatementExecute(request), dvdb.getMessageTimeouts()
218             .getExecReadStoredProcedureTimeout());
219   }
220
221   /**
222    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedCallableStatementExecuteQuery(StoredProcedure)
223    */

224   public ControllerResultSet distributedCallableStatementExecuteQuery(
225       StoredProcedure proc) throws SQLException JavaDoc
226   {
227     StoredProcedureCallResult result = executeRequestReturningStoredProcedureCallResult(
228         proc, new DistributedCallableStatementExecuteQuery(proc), dvdb
229             .getMessageTimeouts().getExecReadStoredProcedureTimeout());
230     return (ControllerResultSet) result.getResult();
231   }
232
233   /**
234    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedCallableStatementExecuteUpdate(org.continuent.sequoia.controller.requests.StoredProcedure)
235    */

236   public ExecuteUpdateResult distributedCallableStatementExecuteUpdate(
237       StoredProcedure proc) throws SQLException JavaDoc
238   {
239     StoredProcedureCallResult result = executeRequestReturningStoredProcedureCallResult(
240         proc, new DistributedCallableStatementExecuteUpdate(proc), dvdb
241             .getMessageTimeouts().getExecWriteStoredProcedureTimeout());
242     return ((ExecuteUpdateResult) result.getResult());
243   }
244
245   /**
246    * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedCallableStatementExecute(StoredProcedure)
247    */

248   public ExecuteResult distributedCallableStatementExecute(StoredProcedure proc)
249       throws SQLException JavaDoc
250   {
251     StoredProcedureCallResult result = executeRequestReturningStoredProcedureCallResult(
252         proc, new DistributedCallableStatementExecute(proc), dvdb
253             .getMessageTimeouts().getExecReadStoredProcedureTimeout());
254     return (ExecuteResult) result.getResult();
255   }
256
257   /**
258    * Execute a distributed request that returns a GeneratedKeysResult.
259    *
260    * @param request the request to execute
261    * @param requestMsg message to be sent through the group communication
262    * @param messageTimeout group message timeout
263    * @return the corresponding ExecuteResult
264    * @throws SQLException if an error occurs
265    */

266   private ExecuteResult executeRequestReturningExecuteResult(
267       AbstractRequest request, DistributedRequest requestMsg,
268       long messageTimeout) throws SQLException JavaDoc
269   {
270     if (dvdb.isProcessMacroBeforeBroadcast())
271       loadBalancer.handleMacros(request);
272     try
273     {
274       ExecuteResult requestResult = null;
275
276       List JavaDoc groupMembers = dvdb.getAllMembers();
277
278       MulticastResponse responses = multicastRequest(request, requestMsg,
279           messageTimeout, groupMembers);
280
281       // List of controllers that gave a AllBackendsFailedException
282
ArrayList JavaDoc failedOnAllBackends = null;
283       // List of controllers that have no more backends to execute queries
284
ArrayList JavaDoc controllersWithoutBackends = null;
285       SQLException JavaDoc exception = null;
286       int size = groupMembers.size();
287       List JavaDoc successfulControllers = null;
288       // Get the result of each controller
289
for (int i = 0; i < size; i++)
290       {
291         Member member = (Member) groupMembers.get(i);
292         if ((responses.getFailedMembers() != null)
293             && responses.getFailedMembers().contains(member))
294         {
295           logger.warn("Controller " + member + " is suspected of failure.");
296           continue;
297         }
298         Object JavaDoc r = responses.getResult(member);
299         if (r instanceof ExecuteResult)
300         {
301           if (requestResult == null)
302             requestResult = (ExecuteResult) r;
303         }
304         else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r))
305         {
306           // Remote controller success
307
if (requestResult == null)
308           {
309             if (successfulControllers == null)
310               successfulControllers = new ArrayList JavaDoc();
311             successfulControllers.add(member);
312           }
313         }
314         else if (r instanceof NoMoreBackendException)
315         {
316           if (controllersWithoutBackends == null)
317             controllersWithoutBackends = new ArrayList JavaDoc();
318           controllersWithoutBackends.add(member);
319           if (logger.isDebugEnabled())
320             logger.debug("Controller " + member
321                 + " has no more backends to execute query (" + r + ")");
322         }
323         else if (r instanceof Exception JavaDoc)
324         {
325           if (failedOnAllBackends == null)
326             failedOnAllBackends = new ArrayList JavaDoc();
327           failedOnAllBackends.add(member);
328           String JavaDoc msg = "Request " + request.getId() + " failed on controller "
329               + member + " (" + r + ")";
330           logger.warn(msg);
331           if (r instanceof SQLException JavaDoc)
332             exception = (SQLException JavaDoc) r;
333           else
334           {
335             exception = new SQLException JavaDoc("Internal exception " + r);
336             exception.initCause((Throwable JavaDoc) r);
337           }
338         }
339         else
340         {
341           if (failedOnAllBackends == null)
342             failedOnAllBackends = new ArrayList JavaDoc();
343           failedOnAllBackends.add(member);
344           if (logger.isWarnEnabled())
345             logger.warn("Unexpected answer from controller " + member + " ("
346                 + r + ") for request "
347                 + request.getSqlShortForm(vdb.getSqlShortFormLength()));
348         }
349       }
350
351       if ((requestResult == null) && (successfulControllers != null))
352       { // Local controller could not get the result, ask it to a successful
353
// remote controller
354
try
355         {
356           requestResult = (ExecuteResult) getRequestResultFromFailoverCache(
357               successfulControllers, request.getId());
358         }
359         catch (NoResultAvailableException e)
360         {
361           exception = new SQLException JavaDoc(
362               "Request '"
363                   + request
364                   + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result");
365         }
366       }
367
368       if ((controllersWithoutBackends != null) || (failedOnAllBackends != null))
369       { // Notify all controllers of completion
370
// Re-create fake stored procedure for proper scheduler notification
371
// (see DistributedStatementExecute#scheduleRequest)
372
StoredProcedure proc = new StoredProcedure(request.getSqlOrTemplate(),
373             request.getEscapeProcessing(), request.getTimeout(), request
374                 .getLineSeparator());
375         proc.setIsAutoCommit(request.isAutoCommit());
376         proc.setTransactionId(request.getTransactionId());
377         proc.setTransactionIsolation(request.getTransactionIsolation());
378         proc.setId(request.getId());
379
380         /*
381          * Notify all controllers where all backend failed (if any) that
382          * completion was 'success'. We determine success from the successful
383          * controllers even though they may have failed afterwards (in which
384          * case requestResult may be null).
385          */

386         boolean success = (requestResult != null || successfulControllers != null);
387         notifyRequestCompletion(proc, success, true, failedOnAllBackends);
388
389         // Notify controllers without active backends (if any)
390
notifyRequestCompletion(proc, success, false,
391             controllersWithoutBackends);
392       }
393
394       if (requestResult != null)
395       {
396         if (logger.isDebugEnabled())
397           logger.debug("Request " + request.getId()
398               + " completed successfully.");
399         return requestResult;
400       }
401
402       // At this point, all controllers failed
403

404       if (exception != null)
405         throw exception;
406       else
407       {
408         String JavaDoc msg = "Request '"
409             + request.getSqlShortForm(vdb.getSqlShortFormLength())
410             + "' failed on all controllers";
411         logger.warn(msg);
412         throw new SQLException JavaDoc(msg);
413       }
414     }
415     catch (SQLException JavaDoc e)
416     {
417       String JavaDoc msg = Translate
418           .get("loadbalancer.request.failed", new String JavaDoc[]{
419               request.getSqlShortForm(vdb.getSqlShortFormLength()),
420               e.getMessage()});
421       logger.warn(msg);
422       throw e;
423     }
424   }
425
426   /**
427    * Execute a distributed request that returns a GeneratedKeysResult.
428    *
429    * @param request the request to execute
430    * @param requestMsg message to be sent through the group communication
431    * @param messageTimeout group message timeout
432    * @return the corresponding GeneratedKeysResult
433    * @throws SQLException if an error occurs
434    */

435   private GeneratedKeysResult executeRequestReturningGeneratedKeys(
436       AbstractRequest request, DistributedRequest requestMsg,
437       long messageTimeout) throws SQLException JavaDoc
438   {
439     if (dvdb.isProcessMacroBeforeBroadcast())
440       loadBalancer.handleMacros(request);
441     try
442     {
443       GeneratedKeysResult requestResult = null;
444
445       List JavaDoc groupMembers = dvdb.getAllMembers();
446
447       MulticastResponse responses = multicastRequest(request, requestMsg,
448           messageTimeout, groupMembers);
449
450       // List of controllers that gave a AllBackendsFailedException
451
ArrayList JavaDoc failedOnAllBackends = null;
452       // List of controllers that gave an inconsistent result
453
ArrayList JavaDoc inconsistentControllers = null;
454       // List of controllers that have no more backends to execute queries
455
ArrayList JavaDoc controllersWithoutBackends = null;
456       SQLException JavaDoc exception = null;
457       List JavaDoc successfulControllers = null;
458       int size = groupMembers.size();
459       // Get the result of each controller
460
for (int i = 0; i < size; i++)
461       {
462         Member member = (Member) groupMembers.get(i);
463         if ((responses.getFailedMembers() != null)
464             && responses.getFailedMembers().contains(member))
465         {
466           logger.warn("Controller " + member + " is suspected of failure.");
467           continue;
468         }
469         Object JavaDoc r = responses.getResult(member);
470         if (r instanceof GeneratedKeysResult)
471         {
472           if (requestResult == null)
473           {
474             requestResult = (GeneratedKeysResult) r;
475           }
476           else
477           {
478             if (requestResult.getUpdateCount() != ((GeneratedKeysResult) r)
479                 .getUpdateCount())
480             {
481               if (inconsistentControllers == null)
482                 inconsistentControllers = new ArrayList JavaDoc();
483               inconsistentControllers.add(member);
484               logger
485                   .error("Controller " + member
486                       + " returned an inconsistent results (" + requestResult
487                       + " when expecting " + r + ") for request "
488                       + request.getId());
489             }
490           }
491         }
492         else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r))
493         {
494           // Remote controller success
495
if (requestResult == null)
496           {
497             if (successfulControllers == null)
498               successfulControllers = new ArrayList JavaDoc();
499             successfulControllers.add(member);
500           }
501         }
502         else if (r instanceof NoMoreBackendException)
503         {
504           if (controllersWithoutBackends == null)
505             controllersWithoutBackends = new ArrayList JavaDoc();
506           controllersWithoutBackends.add(member);
507           if (logger.isDebugEnabled())
508             logger.debug("Controller " + member
509                 + " has no more backends to execute query (" + r + ")");
510         }
511         else if (r instanceof Exception JavaDoc)
512         {
513           if (failedOnAllBackends == null)
514             failedOnAllBackends = new ArrayList JavaDoc();
515           failedOnAllBackends.add(member);
516           String JavaDoc msg = "Request " + request.getId() + " failed on controller "
517               + member + " (" + r + ")";
518           logger.warn(msg);
519           if (r instanceof SQLException JavaDoc)
520             exception = (SQLException JavaDoc) r;
521           else
522           {
523             exception = new SQLException JavaDoc("Internal exception " + r);
524             exception.initCause((Throwable JavaDoc) r);
525           }
526         }
527         else
528         {
529           if (failedOnAllBackends == null)
530             failedOnAllBackends = new ArrayList JavaDoc();
531           failedOnAllBackends.add(member);
532           if (logger.isWarnEnabled())
533             logger.warn("Unexpected answer from controller " + member + " ("
534                 + r + ") for request "
535                 + request.getSqlShortForm(vdb.getSqlShortFormLength()));
536         }
537       }
538
539       if ((requestResult == null) && (successfulControllers != null))
540       { // Local controller could not get the result, ask it to a successful
541
// remote controller
542
try
543         {
544           requestResult = (GeneratedKeysResult) getRequestResultFromFailoverCache(
545               successfulControllers, request.getId());
546         }
547         catch (NoResultAvailableException e)
548         {
549           exception = new SQLException JavaDoc(
550               "Request '"
551                   + request
552                   + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result");
553         }
554       }
555
556       /*
557        * Notify all controllers where all backend failed (if any) that
558        * completion was 'success'. We determine success from the successful
559        * controllers even though they may have failed afterwards (in which case
560        * requestResult may be null).
561        */

562       boolean success = (requestResult != null || successfulControllers != null);
563       notifyRequestCompletion(request, success, true, failedOnAllBackends);
564
565       // Notify controllers without active backends (if any)
566
notifyRequestCompletion(request, success, false,
567           controllersWithoutBackends);
568
569       if (inconsistentControllers != null)
570       { // Notify all inconsistent controllers to disable their backends
571
notifyControllerInconsistency(request, inconsistentControllers);
572       }
573
574       if (requestResult != null)
575       {
576         if (logger.isDebugEnabled())
577           logger.debug("Request " + request.getId()
578               + " completed successfully.");
579         return requestResult;
580       }
581
582       // At this point, all controllers failed
583

584       if (exception != null)
585         throw exception;
586       else
587       {
588         String JavaDoc msg = "Request '" + request + "' failed on all controllers";
589         logger.warn(msg);
590         throw new SQLException JavaDoc(msg);
591       }
592     }
593     catch (SQLException JavaDoc e)
594     {
595       String JavaDoc msg = Translate
596           .get("loadbalancer.request.failed", new String JavaDoc[]{
597               request.getSqlShortForm(vdb.getSqlShortFormLength()),
598               e.getMessage()});
599       logger.warn(msg);
600       throw e;
601     }
602   }
603
604   /**
605    * Execute a distributed request that returns a ResultSet.
606    *
607    * @param request the request to execute
608    * @param requestMsg message to be sent through the group communication
609    * @param messageTimeout group message timeout
610    * @return the corresponding ResultSet
611    * @throws SQLException if an error occurs
612    */

613   private ExecuteUpdateResult executeRequestReturningInt(
614       AbstractRequest request, DistributedRequest requestMsg,
615       long messageTimeout) throws SQLException JavaDoc
616   {
617     if (dvdb.isProcessMacroBeforeBroadcast())
618       loadBalancer.handleMacros(request);
619     try
620     {
621       ExecuteUpdateResult requestResult = null;
622
623       List JavaDoc groupMembers = dvdb.getAllMembers();
624
625       MulticastResponse responses = multicastRequest(request, requestMsg,
626           messageTimeout, groupMembers);
627
628       // List of controllers that gave a AllBackendsFailedException
629
ArrayList JavaDoc failedOnAllBackends = null;
630       // List of controllers that gave an inconsistent result
631
ArrayList JavaDoc inconsistentControllers = null;
632       // List of controllers that have no more backends to execute queries
633
ArrayList JavaDoc controllersWithoutBackends = null;
634       SQLException JavaDoc exception = null;
635       int size = groupMembers.size();
636       // Get the result of each controller
637
for (int i = 0; i < size; i++)
638       {
639         Member member = (Member) groupMembers.get(i);
640         if ((responses.getFailedMembers() != null)
641             && responses.getFailedMembers().contains(member))
642         {
643           logger.warn("Controller " + member + " is suspected of failure.");
644           continue;
645         }
646         Object JavaDoc r = responses.getResult(member);
647         if (r instanceof ExecuteUpdateResult)
648         {
649           if (requestResult == null)
650             requestResult = (ExecuteUpdateResult) r;
651           else
652           {
653             if (requestResult.getUpdateCount() != ((ExecuteUpdateResult) r)
654                 .getUpdateCount())
655             {
656               if (inconsistentControllers == null)
657                 inconsistentControllers = new ArrayList JavaDoc();
658               inconsistentControllers.add(member);
659               logger.error("Controller " + member
660                   + " returned an inconsistent results ("
661                   + requestResult.getUpdateCount() + " when expecting "
662                   + ((ExecuteUpdateResult) r).getUpdateCount()
663                   + ") for request " + request.getId());
664             }
665           }
666         }
667         else if (r instanceof NoMoreBackendException)
668         {
669           if (controllersWithoutBackends == null)
670             controllersWithoutBackends = new ArrayList JavaDoc();
671           controllersWithoutBackends.add(member);
672           if (logger.isDebugEnabled())
673             logger.debug("Controller " + member
674                 + " has no more backends to execute query (" + r + ")");
675         }
676         else if (r instanceof Exception JavaDoc)
677         {
678           if (failedOnAllBackends == null)
679             failedOnAllBackends = new ArrayList JavaDoc();
680           failedOnAllBackends.add(member);
681           String JavaDoc msg = "Request " + request.getId() + " failed on controller "
682               + member + " (" + r + ")";
683           logger.warn(msg);
684           if (r instanceof SQLException JavaDoc)
685             exception = (SQLException JavaDoc) r;
686           else
687           {
688             exception = new SQLException JavaDoc("Internal exception " + r);
689             exception.initCause((Throwable JavaDoc) r);
690           }
691         }
692         else
693         {
694           if (failedOnAllBackends == null)
695             failedOnAllBackends = new ArrayList JavaDoc();
696           failedOnAllBackends.add(member);
697           if (logger.isWarnEnabled())
698             logger.warn("Unexpected answer from controller " + member + " ("
699                 + r + ") for request "
700                 + request.getSqlShortForm(vdb.getSqlShortFormLength()));
701         }
702       }
703
704       // Notify all controllers where all backends failed (if any) that
705
// completion was 'success'
706
notifyRequestCompletion(request, requestResult != null, true,
707           failedOnAllBackends);
708
709       // Notify controllers without active backends (if any)
710
notifyRequestCompletion(request, requestResult != null, false,
711           controllersWithoutBackends);
712
713       if (inconsistentControllers != null)
714       { // Notify all inconsistent controllers to disable their backends
715
notifyControllerInconsistency(request, inconsistentControllers);
716       }
717
718       if (requestResult != null)
719       {
720         if (logger.isDebugEnabled())
721           logger.debug("Request " + request.getId()
722               + " completed successfully.");
723         return requestResult;
724       }
725
726       // At this point, all controllers failed
727

728       if (exception != null)
729         throw exception;
730       else
731       {
732         String JavaDoc msg = "Request '" + request + "' failed on all controllers";
733         logger.warn(msg);
734         throw new SQLException JavaDoc(msg);
735       }
736     }
737     catch (SQLException JavaDoc e)
738     {
739       String JavaDoc msg = Translate
740           .get("loadbalancer.request.failed", new String JavaDoc[]{
741               request.getSqlShortForm(vdb.getSqlShortFormLength()),
742               e.getMessage()});
743       logger.warn(msg);
744       throw e;
745     }
746   }
747
748   /**
749    * Execute a distributed request that returns a ResultSet.
750    *
751    * @param request the request to execute
752    * @param requestMsg message to be sent through the group communication
753    * @param messageTimeout group message timeout
754    * @return the corresponding ResultSet
755    * @throws SQLException if an error occurs
756    */

757   private ControllerResultSet executeRequestReturningResultSet(
758       AbstractRequest request, DistributedRequest requestMsg,
759       long messageTimeout) throws SQLException JavaDoc
760   {
761     if (dvdb.isProcessMacroBeforeBroadcast())
762       loadBalancer.handleMacros(request);
763     try
764     {
765       ControllerResultSet requestResult = null;
766
767       List JavaDoc groupMembers = dvdb.getAllMembers();
768
769       MulticastResponse responses = multicastRequest(request, requestMsg,
770           messageTimeout, groupMembers);
771
772       // List of controllers that gave a AllBackendsFailedException
773
ArrayList JavaDoc failedOnAllBackends = null;
774       // List of controllers that have no more backends to execute queries
775
ArrayList JavaDoc controllersWithoutBackends = null;
776       SQLException JavaDoc exception = null;
777       int size = groupMembers.size();
778       List JavaDoc successfulControllers = null;
779       // Get the result of each controller
780
for (int i = 0; i < size; i++)
781       {
782         Member member = (Member) groupMembers.get(i);
783         if ((responses.getFailedMembers() != null)
784             && responses.getFailedMembers().contains(member))
785         {
786           logger.warn("Controller " + member + " is suspected of failure.");
787           continue;
788         }
789         Object JavaDoc r = responses.getResult(member);
790         if (r instanceof ControllerResultSet)
791         {
792           if (requestResult == null)
793             requestResult = (ControllerResultSet) r;
794         }
795         else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r))
796         {
797           // Remote controller success
798
if (requestResult == null)
799           {
800             if (successfulControllers == null)
801               successfulControllers = new ArrayList JavaDoc();
802             successfulControllers.add(member);
803           }
804         }
805         else if (r instanceof NoMoreBackendException)
806         {
807           if (controllersWithoutBackends == null)
808             controllersWithoutBackends = new ArrayList JavaDoc();
809           controllersWithoutBackends.add(member);
810           if (logger.isDebugEnabled())
811             logger.debug("Controller " + member
812                 + " has no more backends to execute query (" + r + ")");
813         }
814         else if (r instanceof Exception JavaDoc)
815         {
816           if (failedOnAllBackends == null)
817             failedOnAllBackends = new ArrayList JavaDoc();
818           failedOnAllBackends.add(member);
819           String JavaDoc msg = "Request " + request.getId() + " failed on controller "
820               + member + " (" + r + ")";
821           logger.warn(msg);
822           if (r instanceof SQLException JavaDoc)
823             exception = (SQLException JavaDoc) r;
824           else
825           {
826             exception = new SQLException JavaDoc("Internal exception " + r);
827             exception.initCause((Throwable JavaDoc) r);
828           }
829         }
830         else
831         {
832           if (failedOnAllBackends == null)
833             failedOnAllBackends = new ArrayList JavaDoc();
834           failedOnAllBackends.add(member);
835           if (logger.isWarnEnabled())
836             logger.warn("Unexpected answer from controller " + member + " ("
837                 + r + ") for request "
838                 + request.getSqlShortForm(vdb.getSqlShortFormLength()));
839         }
840       }
841
842       if ((requestResult == null) && (successfulControllers != null))
843       { // Local controller could not get the result, ask it to a successful
844
// remote controller
845
try
846         {
847           requestResult = (ControllerResultSet) getRequestResultFromFailoverCache(
848               successfulControllers, request.getId());
849         }
850         catch (NoResultAvailableException e)
851         {
852           exception = new SQLException JavaDoc(
853               "Request '"
854                   + request
855                   + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result");
856         }
857       }
858
859       /*
860        * Notify all controllers where all backend failed (if any) that
861        * completion was 'success'. We determine success from the successful
862        * controllers even though they may have failed afterwards (in which case
863        * requestResult may be null).
864        */

865       boolean success = (requestResult != null || successfulControllers != null);
866       notifyRequestCompletion(request, success, true, failedOnAllBackends);
867
868       // Notify controllers without active backends (if any)
869
notifyRequestCompletion(request, success, false,
870           controllersWithoutBackends);
871
872       if (requestResult != null)
873       {
874         if (logger.isDebugEnabled())
875           logger.debug("Request " + request.getId()
876               + " completed successfully.");
877         return requestResult;
878       }
879
880       // At this point, all controllers failed
881

882       if (exception != null)
883         throw exception;
884       else
885       {
886         String JavaDoc msg = "Request '" + request + "' failed on all controllers";
887         logger.warn(msg);
888         throw new SQLException JavaDoc(msg);
889       }
890     }
891     catch (SQLException JavaDoc e)
892     {
893       String JavaDoc msg = Translate
894           .get("loadbalancer.request.failed", new String JavaDoc[]{
895               request.getSqlShortForm(vdb.getSqlShortFormLength()),
896               e.getMessage()});
897       logger.warn(msg);
898       throw e;
899     }
900   }
901
902   /**
903    * Execute a distributed request (usually a stored procedure) that returns a
904    * StoredProcedureCallResult.
905    *
906    * @param proc the stored procedure to execute
907    * @param requestMsg message to be sent through the group communication
908    * @param messageTimeout group message timeout
909    * @return the corresponding StoredProcedureCallResult
910    * @throws SQLException if an error occurs
911    */

912   private StoredProcedureCallResult executeRequestReturningStoredProcedureCallResult(
913       StoredProcedure proc, DistributedRequest requestMsg, long messageTimeout)
914       throws SQLException JavaDoc
915   {
916     if (dvdb.isProcessMacroBeforeBroadcast())
917       loadBalancer.handleMacros(proc);
918     try
919     {
920       StoredProcedureCallResult result = null;
921
922       List JavaDoc groupMembers = dvdb.getAllMembers();
923
924       MulticastResponse responses = multicastRequest(proc, requestMsg,
925           messageTimeout, groupMembers);
926
927       // List of controllers that gave a AllBackendsFailedException
928
ArrayList JavaDoc failedOnAllBackends = null;
929       // List of controllers that have no more backends to execute queries
930
ArrayList JavaDoc controllersWithoutBackends = null;
931       SQLException JavaDoc exception = null;
932       int size = groupMembers.size();
933       List JavaDoc successfulControllers = null;
934       // Get the result of each controller
935
for (int i = 0; i < size; i++)
936       {
937         Member member = (Member) groupMembers.get(i);
938         if ((responses.getFailedMembers() != null)
939             && responses.getFailedMembers().contains(member))
940         {
941           logger.warn("Controller " + member + " is suspected of failure.");
942           continue;
943         }
944         Object JavaDoc r = responses.getResult(member);
945         if (r instanceof StoredProcedureCallResult)
946         {
947           if (result == null)
948             result = (StoredProcedureCallResult) r;
949         }
950         else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r))
951         {
952           // Remote controller success
953
if (result == null)
954           {
955             if (successfulControllers == null)
956               successfulControllers = new ArrayList JavaDoc();
957             successfulControllers.add(member);
958           }
959         }
960         else if (r instanceof NoMoreBackendException)
961         {
962           if (controllersWithoutBackends == null)
963             controllersWithoutBackends = new ArrayList JavaDoc();
964           controllersWithoutBackends.add(member);
965           if (logger.isDebugEnabled())
966             logger.debug("Controller " + member
967                 + " has no more backends to execute query (" + r + ")");
968         }
969         else if (r instanceof Exception JavaDoc)
970         {
971           if (failedOnAllBackends == null)
972             failedOnAllBackends = new ArrayList JavaDoc();
973           failedOnAllBackends.add(member);
974           String JavaDoc msg = "Request " + proc.getId() + " failed on controller "
975               + member + " (" + r + ")";
976           logger.warn(msg);
977           if (r instanceof SQLException JavaDoc)
978             exception = (SQLException JavaDoc) r;
979           else
980           {
981             exception = new SQLException JavaDoc("Internal exception " + r);
982             exception.initCause((Throwable JavaDoc) r);
983           }
984         }
985         else
986         {
987           if (failedOnAllBackends == null)
988             failedOnAllBackends = new ArrayList JavaDoc();
989           failedOnAllBackends.add(member);
990           if (logger.isWarnEnabled())
991             logger.warn("Unexpected answer from controller " + member + " ("
992                 + r + ") for request "
993                 + proc.getSqlShortForm(vdb.getSqlShortFormLength()));
994         }
995       }
996
997       if ((result == null) && (successfulControllers != null))
998       { // Local controller could not get the result, ask it to a successful
999
// remote controller
1000
try
1001        {
1002          result = (StoredProcedureCallResult) getRequestResultFromFailoverCache(
1003              successfulControllers, proc.getId());
1004        }
1005        catch (NoResultAvailableException e)
1006        {
1007          exception = new SQLException JavaDoc(
1008              "Request '"
1009                  + proc
1010                  + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result");
1011        }
1012      }
1013
1014      /*
1015       * Notify all controllers where all backend failed (if any) that
1016       * completion was 'success'. We determine success from the successful
1017       * controllers even though they may have failed afterwards (in which case
1018       * requestResult may be null).
1019       */

1020      boolean success = (result != null || successfulControllers != null);
1021      notifyRequestCompletion(proc, success, true, failedOnAllBackends);
1022
1023      // Notify controllers without active backends (if any)
1024
notifyRequestCompletion(proc, success, false, controllersWithoutBackends);
1025
1026      if (result != null)
1027      {
1028        proc.copyNamedAndOutParameters(result.getStoredProcedure());
1029        if (logger.isDebugEnabled())
1030          logger.debug("Request " + proc.getId() + " completed successfully.");
1031        return result;
1032      }
1033
1034      // At this point, all controllers failed
1035

1036      if (exception != null)
1037        throw exception;
1038      else
1039      {
1040        String JavaDoc msg = "Request '" + proc + "' failed on all controllers";
1041        logger.warn(msg);
1042        throw new SQLException JavaDoc(msg);
1043      }
1044    }
1045    catch (SQLException JavaDoc e)
1046    {
1047      String JavaDoc msg = Translate.get("loadbalancer.request.failed", new String JavaDoc[]{
1048          proc.getSqlShortForm(vdb.getSqlShortFormLength()), e.getMessage()});
1049      logger.warn(msg);
1050      throw e;
1051    }
1052  }
1053
1054  /**
1055   * Multicast a request to a set of controllers.
1056   *
1057   * @param request the request that is executed
1058   * @param requestMsg the group message to send
1059   * @param messageTimeout timeout on the group message
1060   * @param groupMembers list of controllers to send the message to
1061   * @return the responses to the multicast
1062   * @throws SQLException if an error occurs
1063   */

1064  private MulticastResponse multicastRequest(AbstractRequest request,
1065      Serializable JavaDoc requestMsg, long messageTimeout, List JavaDoc groupMembers)
1066      throws SQLException JavaDoc
1067  {
1068    if (logger.isDebugEnabled())
1069      logger.debug("Broadcasting request "
1070          + request.getSqlShortForm(dvdb.getSqlShortFormLength())
1071          + (request.isAutoCommit() ? "" : " transaction "
1072              + request.getTransactionId()) + " to all controllers ("
1073          + dvdb.getChannel().getLocalMembership() + "->"
1074          + groupMembers.toString() + ")");
1075
1076    // Send the query to everybody including us
1077
MulticastResponse responses;
1078    try
1079    {
1080      // Warning! Message timeouts are in ms but request timeout is in seconds
1081
responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1082          groupMembers,
1083          requestMsg,
1084          MulticastRequestAdapter.WAIT_ALL,
1085          MessageTimeouts.getMinTimeout(messageTimeout,
1086              request.getTimeout() * 1000L));
1087    }
1088    catch (Exception JavaDoc e)
1089    {
1090      String JavaDoc msg = "An error occured while executing distributed request "
1091          + request.getId();
1092      logger.warn(msg, e);
1093      throw new SQLException JavaDoc(msg + " (" + e + ")");
1094    }
1095
1096    if (logger.isDebugEnabled())
1097      logger.debug("Request "
1098          + request.getSqlShortForm(dvdb.getSqlShortFormLength())
1099          + " completed.");
1100
1101    if (responses.getFailedMembers() != null)
1102    { // Some controllers failed ... too bad !
1103
logger.warn(responses.getFailedMembers().size()
1104          + " controller(s) died during execution of request "
1105          + request.getId());
1106    }
1107    return responses;
1108  }
1109
1110  /**
1111   * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedAbort(String,
1112   * long)
1113   */

1114  public void distributedAbort(String JavaDoc login, long transactionId)
1115      throws SQLException JavaDoc
1116  {
1117    try
1118    {
1119      List JavaDoc groupMembers = dvdb.getAllMembers();
1120
1121      AbstractRequest abortRequest = new UnknownWriteRequest("abort", false, 0,
1122          "\n");
1123      abortRequest.setTransactionId(transactionId);
1124
1125      MulticastResponse responses = multicastRequest(abortRequest,
1126          new DistributedAbort(login, transactionId), dvdb.getMessageTimeouts()
1127              .getRollbackTimeout(), groupMembers);
1128
1129      if (logger.isDebugEnabled())
1130        logger.debug("Abort of transaction " + transactionId + " completed.");
1131
1132      // List of controllers that have no more backends to execute queries
1133
ArrayList JavaDoc controllersWithoutBackends = null;
1134      SQLException JavaDoc exception = null;
1135      int size = groupMembers.size();
1136      boolean success = false;
1137      // Get the result of each controller
1138
for (int i = 0; i < size; i++)
1139      {
1140        Member member = (Member) groupMembers.get(i);
1141        if ((responses.getFailedMembers() != null)
1142            && responses.getFailedMembers().contains(member))
1143        {
1144          logger.warn("Controller " + member + " is suspected of failure.");
1145          continue;
1146        }
1147        Object JavaDoc r = responses.getResult(member);
1148        if (r instanceof Boolean JavaDoc)
1149        {
1150          if (((Boolean JavaDoc) r).booleanValue())
1151            success = true;
1152          else
1153            logger.error("Unexpected result for controller " + member);
1154        }
1155        else if (r instanceof NoMoreBackendException)
1156        {
1157          if (controllersWithoutBackends == null)
1158            controllersWithoutBackends = new ArrayList JavaDoc();
1159          controllersWithoutBackends.add(member);
1160          if (logger.isDebugEnabled())
1161            logger.debug("Controller " + member
1162                + " has no more backends to abort transaction "
1163                + transactionId + " (" + r + ")");
1164        }
1165      }
1166
1167      // Notify controllers without active backends
1168
notifyRequestCompletion(abortRequest, success, false,
1169          controllersWithoutBackends);
1170
1171      if (success)
1172        return; // This is a success if at least one controller has succeeded
1173

1174      if (exception != null)
1175        throw exception;
1176
1177      // At this point, all controllers failed
1178

1179      String JavaDoc msg = "Transaction " + transactionId
1180          + " failed to abort on all controllers";
1181      logger.warn(msg);
1182      throw new SQLException JavaDoc(msg);
1183    }
1184    catch (SQLException JavaDoc e)
1185    {
1186      String JavaDoc msg = "Transaction " + transactionId + " abort failed (" + e + ")";
1187      logger.warn(msg);
1188      throw e;
1189    }
1190  }
1191
1192  /**
1193   * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedCommit(String,
1194   * long)
1195   */

1196  public void distributedCommit(String JavaDoc login, long transactionId)
1197      throws SQLException JavaDoc
1198  {
1199    try
1200    {
1201      List JavaDoc groupMembers = dvdb.getAllMembers();
1202      AbstractRequest commitRequest = new UnknownWriteRequest("commit", false,
1203          0, "\n");
1204      commitRequest.setTransactionId(transactionId);
1205      commitRequest.setLogin(login);
1206      commitRequest.setIsAutoCommit(false);
1207
1208      MulticastResponse responses = multicastRequest(commitRequest,
1209          new DistributedCommit(login, transactionId), dvdb
1210              .getMessageTimeouts().getCommitTimeout(), groupMembers);
1211
1212      if (logger.isDebugEnabled())
1213        logger.debug("Commit of transaction " + transactionId + " completed.");
1214
1215      // List of controllers that gave a AllBackendsFailedException
1216
ArrayList JavaDoc failedOnAllBackends = null;
1217      // List of controllers that have no more backends to execute queries
1218
ArrayList JavaDoc controllersWithoutBackends = null;
1219      SQLException JavaDoc exception = null;
1220      // get a list that won't change while we go through it
1221
groupMembers = dvdb.getAllMembers();
1222      int size = groupMembers.size();
1223      boolean success = false;
1224      // Get the result of each controller
1225
for (int i = 0; i < size; i++)
1226      {
1227        Member member = (Member) groupMembers.get(i);
1228        if ((responses.getFailedMembers() != null)
1229            && responses.getFailedMembers().contains(member))
1230        {
1231          logger.warn("Controller " + member + " is suspected of failure.");
1232          continue;
1233        }
1234        Object JavaDoc r = responses.getResult(member);
1235        if (r instanceof Boolean JavaDoc)
1236        {
1237          if (((Boolean JavaDoc) r).booleanValue())
1238            success = true;
1239          else
1240            logger.error("Unexpected result for controller " + member);
1241        }
1242        else if (r instanceof NoMoreBackendException)
1243        {
1244          if (controllersWithoutBackends == null)
1245            controllersWithoutBackends = new ArrayList JavaDoc();
1246          controllersWithoutBackends.add(member);
1247          if (logger.isDebugEnabled())
1248            logger.debug("Controller " + member
1249                + " has no more backends to commit transaction "
1250                + transactionId + " (" + r + ")");
1251        }
1252        else if (r instanceof AllBackendsFailedException)
1253        {
1254          if (failedOnAllBackends == null)
1255            failedOnAllBackends = new ArrayList JavaDoc();
1256          failedOnAllBackends.add(member);
1257          if (logger.isDebugEnabled())
1258            logger.debug("Commit failed on all backends of controller "
1259                + member + " (" + r + ")");
1260        }
1261        else if (r instanceof SQLException JavaDoc)
1262        {
1263          if (failedOnAllBackends == null)
1264            failedOnAllBackends = new ArrayList JavaDoc();
1265          failedOnAllBackends.add(member);
1266          String JavaDoc msg = "Commit of transaction " + transactionId
1267              + " failed on controller " + member + " (" + r + ")";
1268          logger.warn(msg);
1269          exception = (SQLException JavaDoc) r;
1270        }
1271      }
1272
1273      // Notify all controllers where all backend failed (if any) that
1274
// completion was 'success'
1275
notifyRequestCompletion(commitRequest, success, true, failedOnAllBackends);
1276
1277      // Notify controllers without active backends (if any)
1278
notifyRequestCompletion(commitRequest, success, false,
1279          controllersWithoutBackends);
1280
1281      if (success)
1282        return; // This is a success if at least one controller has succeeded
1283

1284      // At this point, all controllers failed
1285

1286      if (exception != null)
1287        throw exception;
1288      else
1289      {
1290        String JavaDoc msg = "Transaction " + transactionId
1291            + " failed to commit on all controllers";
1292        logger.warn(msg);
1293        throw new SQLException JavaDoc(msg);
1294      }
1295    }
1296    catch (SQLException JavaDoc e)
1297    {
1298      String JavaDoc msg = "Transaction " + transactionId + " commit failed (" + e
1299          + ")";
1300      logger.warn(msg);
1301      throw e;
1302    }
1303  }
1304
1305  /**
1306   * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedRollback(String,
1307   * long)
1308   */

1309  public void distributedRollback(String JavaDoc login, long transactionId)
1310      throws SQLException JavaDoc
1311  {
1312    try
1313    {
1314      List JavaDoc groupMembers = dvdb.getAllMembers();
1315
1316      AbstractRequest rollbackRequest = new UnknownWriteRequest("rollback",
1317          false, 0, "\n");
1318      rollbackRequest.setTransactionId(transactionId);
1319      rollbackRequest.setLogin(login);
1320      rollbackRequest.setIsAutoCommit(false);
1321
1322      MulticastResponse responses = multicastRequest(rollbackRequest,
1323          new DistributedRollback(login, transactionId), dvdb
1324              .getMessageTimeouts().getRollbackTimeout(), groupMembers);
1325
1326      if (logger.isDebugEnabled())
1327        logger
1328            .debug("Rollback of transaction " + transactionId + " completed.");
1329
1330      // List of controllers that gave a AllBackendsFailedException
1331
ArrayList JavaDoc failedOnAllBackends = null;
1332      // List of controllers that have no more backends to execute queries
1333
ArrayList JavaDoc controllersWithoutBackends = null;
1334      SQLException JavaDoc exception = null;
1335
1336      // get a list that won't change while we go through it
1337
groupMembers = dvdb.getAllMembers();
1338      int size = groupMembers.size();
1339      boolean success = false;
1340      // Get the result of each controller
1341
for (int i = 0; i < size; i++)
1342      {
1343        Member member = (Member) groupMembers.get(i);
1344        if ((responses.getFailedMembers() != null)
1345            && responses.getFailedMembers().contains(member))
1346        {
1347          logger.warn("Controller " + member + " is suspected of failure.");
1348          continue;
1349        }
1350        Object JavaDoc r = responses.getResult(member);
1351        if (r instanceof Boolean JavaDoc)
1352        {
1353          if (((Boolean JavaDoc) r).booleanValue())
1354            success = true;
1355          else
1356            logger.error("Unexpected result for controller " + member);
1357        }
1358        else if (r instanceof NoMoreBackendException)
1359        {
1360          if (controllersWithoutBackends == null)
1361            controllersWithoutBackends = new ArrayList JavaDoc();
1362          controllersWithoutBackends.add(member);
1363          if (logger.isDebugEnabled())
1364            logger.debug("Controller " + member
1365                + " has no more backends to rollback transaction "
1366                + transactionId + " (" + r + ")");
1367        }
1368        else if (r instanceof AllBackendsFailedException)
1369        {
1370          if (failedOnAllBackends == null)
1371            failedOnAllBackends = new ArrayList JavaDoc();
1372          failedOnAllBackends.add(member);
1373          if (logger.isDebugEnabled())
1374            logger.debug("Rollback failed on all backends of controller "
1375                + member + " (" + r + ")");
1376        }
1377        else if (r instanceof SQLException JavaDoc)
1378        {
1379          if (failedOnAllBackends == null)
1380            failedOnAllBackends = new ArrayList JavaDoc();
1381          failedOnAllBackends.add(member);
1382          String JavaDoc msg = "Rollback of transaction " + transactionId
1383              + " failed on controller " + member + " (" + r + ")";
1384          logger.warn(msg);
1385          exception = (SQLException JavaDoc) r;
1386        }
1387      }
1388
1389      // Notify all controllers where all backend failed (if any) that
1390
// completion was 'success'
1391
notifyRequestCompletion(rollbackRequest, success, true,
1392          failedOnAllBackends);
1393
1394      // Notify controllers without active backends (if any)
1395
notifyRequestCompletion(rollbackRequest, success, false,
1396          controllersWithoutBackends);
1397
1398      if (success)
1399        return; // This is a success if at least one controller has succeeded
1400

1401      if (exception != null)
1402        throw exception;
1403
1404      // At this point, all controllers failed
1405

1406      String JavaDoc msg = "Transaction " + transactionId
1407          + " failed to rollback on all controllers";
1408      logger.warn(msg);
1409      throw new SQLException JavaDoc(msg);
1410    }
1411    catch (SQLException JavaDoc e)
1412    {
1413      String JavaDoc msg = "Transaction " + transactionId + " rollback failed (" + e
1414          + ")";
1415      logger.warn(msg);
1416      throw e;
1417    }
1418  }
1419
1420  /**
1421   * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedRollback(String,
1422   * long, String)
1423   */

1424  public void distributedRollback(String JavaDoc login, long transactionId,
1425      String JavaDoc savepointName) throws SQLException JavaDoc
1426  {
1427    try
1428    {
1429      List JavaDoc groupMembers = dvdb.getAllMembers();
1430
1431      AbstractRequest rollbackRequest = new UnknownWriteRequest("rollback "
1432          + savepointName, false, 0, "\n");
1433      rollbackRequest.setTransactionId(transactionId);
1434      rollbackRequest.setLogin(login);
1435      rollbackRequest.setIsAutoCommit(false);
1436
1437      MulticastResponse responses = multicastRequest(rollbackRequest,
1438          new DistributedRollbackToSavepoint(transactionId, savepointName),
1439          dvdb.getMessageTimeouts().getRollbackToSavepointTimeout(),
1440          groupMembers);
1441
1442      if (logger.isDebugEnabled())
1443        logger.debug("Rollback to savepoint " + savepointName + " for "
1444            + "transaction " + transactionId + " completed.");
1445
1446      // List of controllers that gave a AllBackendsFailedException
1447
ArrayList JavaDoc failedOnAllBackends = null;
1448      // List of controllers that have no more backends to execute queries
1449
ArrayList JavaDoc controllersWithoutBackends = null;
1450      SQLException JavaDoc exception = null;
1451
1452      // get a list that won't change while we go through it
1453
groupMembers = dvdb.getAllMembers();
1454      int size = groupMembers.size();
1455      boolean success = false;
1456      // Get the result of each controller
1457
for (int i = 0; i < size; i++)
1458      {
1459        Member member = (Member) groupMembers.get(i);
1460        if ((responses.getFailedMembers() != null)
1461            && responses.getFailedMembers().contains(member))
1462        {
1463          logger.warn("Controller " + member + " is suspected of failure.");
1464          continue;
1465        }
1466        Object JavaDoc r = responses.getResult(member);
1467        if (r instanceof Boolean JavaDoc)
1468        {
1469          if (((Boolean JavaDoc) r).booleanValue())
1470            success = true;
1471          else
1472            logger.error("Unexpected result for controller " + member);
1473        }
1474        else if (r instanceof NoMoreBackendException)
1475        {
1476          if (controllersWithoutBackends == null)
1477            controllersWithoutBackends = new ArrayList JavaDoc();
1478          controllersWithoutBackends.add(member);
1479          if (logger.isDebugEnabled())
1480            logger.debug("Controller " + member + " has no more backends to "
1481                + "rollback to savepoint " + savepointName + " for "
1482                + "transaction " + transactionId + " (" + r + ")");
1483        }
1484        else if (r instanceof AllBackendsFailedException)
1485        {
1486          if (failedOnAllBackends == null)
1487            failedOnAllBackends = new ArrayList JavaDoc();
1488          failedOnAllBackends.add(member);
1489          if (logger.isDebugEnabled())
1490            logger.debug("rollback to savepoint failed on all backends of "
1491                + "controller " + member + " (" + r + ")");
1492        }
1493        else if (r instanceof SQLException JavaDoc)
1494        {
1495          if (failedOnAllBackends == null)
1496            failedOnAllBackends = new ArrayList JavaDoc();
1497          failedOnAllBackends.add(member);
1498          String JavaDoc msg = "rollback to savepoint " + savepointName + " for "
1499              + "transaction " + transactionId + " failed on controller "
1500              + member + " (" + r + ")";
1501          logger.warn(msg);
1502          exception = (SQLException JavaDoc) r;
1503        }
1504      }
1505
1506      // Notify all controllers where all backend failed (if any) that
1507
// completion was 'success'
1508
notifyRequestCompletion(rollbackRequest, success, true,
1509          failedOnAllBackends);
1510
1511      // Notify controllers without active backends (if any)
1512
notifyRequestCompletion(rollbackRequest, success, false,
1513          controllersWithoutBackends);
1514
1515      if (success)
1516        return; // This is a success if at least one controller has succeeded
1517

1518      if (exception != null)
1519        throw exception;
1520
1521      // At this point, all controllers failed
1522

1523      if (exception != null)
1524        throw exception;
1525      else
1526      {
1527        String JavaDoc msg = "Rollback to savepoint " + savepointName + " for "
1528            + "transaction " + transactionId + " failed on all controllers";
1529        logger.warn(msg);
1530        throw new SQLException JavaDoc(msg);
1531      }
1532    }
1533    catch (SQLException JavaDoc e)
1534    {
1535      String JavaDoc msg = "Rollback to savepoint " + savepointName + " for "
1536          + "transaction " + transactionId + " failed (" + e + ")";
1537      logger.warn(msg);
1538      throw e;
1539    }
1540  }
1541
1542  /**
1543   * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedSetSavepoint(String,
1544   * long, String)
1545   */

1546  public void distributedSetSavepoint(String JavaDoc login, long transactionId,
1547      String JavaDoc name) throws SQLException JavaDoc
1548  {
1549    try
1550    {
1551      List JavaDoc groupMembers = dvdb.getAllMembers();
1552
1553      AbstractRequest setSavepointRequest = new UnknownWriteRequest(
1554          "savepoint " + name, false, 0, "\n");
1555      setSavepointRequest.setTransactionId(transactionId);
1556      setSavepointRequest.setLogin(login);
1557      setSavepointRequest.setIsAutoCommit(false);
1558
1559      MulticastResponse responses = multicastRequest(setSavepointRequest,
1560          new DistributedSetSavepoint(login, transactionId, name), dvdb
1561              .getMessageTimeouts().getSetSavepointTimeout(), groupMembers);
1562
1563      if (logger.isDebugEnabled())
1564        logger.debug("Set savepoint " + name + " to transaction "
1565            + transactionId + " completed.");
1566
1567      // List of controllers that gave a AllBackendsFailedException
1568
ArrayList JavaDoc failedOnAllBackends = null;
1569      // List of controllers that have no more backends to execute queries
1570
ArrayList JavaDoc controllersWithoutBackends = null;
1571      SQLException JavaDoc exception = null;
1572
1573      // get a list that won't change while we go through it
1574
groupMembers = dvdb.getAllMembers();
1575      int size = groupMembers.size();
1576      boolean success = false;
1577      // Get the result of each controller
1578
for (int i = 0; i < size; i++)
1579      {
1580        Member member = (Member) groupMembers.get(i);
1581        if ((responses.getFailedMembers() != null)
1582            && responses.getFailedMembers().contains(member))
1583        {
1584          logger.warn("Controller " + member + " is suspected of failure.");
1585          continue;
1586        }
1587        Object JavaDoc r = responses.getResult(member);
1588        if (r instanceof Boolean JavaDoc)
1589        {
1590          if (((Boolean JavaDoc) r).booleanValue())
1591            success = true;
1592          else
1593            logger.error("Unexpected result for controller " + member);
1594        }
1595        else if (r instanceof NoMoreBackendException)
1596        {
1597          if (controllersWithoutBackends == null)
1598            controllersWithoutBackends = new ArrayList JavaDoc();
1599          controllersWithoutBackends.add(member);
1600          if (logger.isDebugEnabled())
1601            logger.debug("Controller " + member + " has no more backends to "
1602                + "set savepoint " + name + " to transaction " + transactionId
1603                + " (" + r + ")");
1604        }
1605        else if (r instanceof AllBackendsFailedException)
1606        {
1607          if (failedOnAllBackends == null)
1608            failedOnAllBackends = new ArrayList JavaDoc();
1609          failedOnAllBackends.add(member);
1610          if (logger.isDebugEnabled())
1611            logger.debug("set savepoint failed on all backends of controller "
1612                + member + " (" + r + ")");
1613        }
1614        else if (r instanceof SQLException JavaDoc)
1615        {
1616          if (failedOnAllBackends == null)
1617            failedOnAllBackends = new ArrayList JavaDoc();
1618          failedOnAllBackends.add(member);
1619          String JavaDoc msg = "set savepoint " + name + " to transaction "
1620              + transactionId + " failed on controller " + member + " (" + r
1621              + ")";
1622          logger.warn(msg);
1623          exception = (SQLException JavaDoc) r;
1624        }
1625      }
1626
1627      // Notify all controllers where all backend failed (if any) that
1628
// completion was 'success'
1629
notifyRequestCompletion(setSavepointRequest, success, true,
1630          failedOnAllBackends);
1631
1632      // Notify controllers without active backends (if any)
1633
notifyRequestCompletion(setSavepointRequest, success, false,
1634          controllersWithoutBackends);
1635
1636      if (success)
1637        return; // This is a success if at least one controller has succeeded
1638

1639      if (exception != null)
1640        throw exception;
1641
1642      // At this point, all controllers failed
1643

1644      if (exception != null)
1645        throw exception;
1646      else
1647      {
1648        String JavaDoc msg = "Set savepoint " + name + " to transaction "
1649            + transactionId + " failed on all controllers";
1650        logger.warn(msg);
1651        throw new SQLException JavaDoc(msg);
1652      }
1653    }
1654    catch (SQLException JavaDoc e)
1655    {
1656      String JavaDoc msg = "Set savepoint " + name + " to transaction " + transactionId
1657          + " failed (" + e + ")";
1658      logger.warn(msg);
1659      throw e;
1660    }
1661  }
1662
1663  /**
1664   * @see org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager#distributedReleaseSavepoint(String,
1665   * long, String)
1666   */

1667  public void distributedReleaseSavepoint(String JavaDoc login, long transactionId,
1668      String JavaDoc name) throws SQLException JavaDoc
1669  {
1670    try
1671    {
1672      List JavaDoc groupMembers = dvdb.getAllMembers();
1673
1674      AbstractRequest releaseSavepointRequest = new UnknownWriteRequest(
1675          "release " + name, false, 0, "\n");
1676      releaseSavepointRequest.setTransactionId(transactionId);
1677      releaseSavepointRequest.setLogin(login);
1678      releaseSavepointRequest.setIsAutoCommit(false);
1679
1680      MulticastResponse responses = multicastRequest(releaseSavepointRequest,
1681          new DistributedReleaseSavepoint(transactionId, name), dvdb
1682              .getMessageTimeouts().getReleaseSavepointTimeout(), groupMembers);
1683
1684      if (logger.isDebugEnabled())
1685        logger.debug("Release savepoint " + name + " from transaction "
1686            + transactionId + " completed.");
1687
1688      // List of controllers that gave a AllBackendsFailedException
1689
ArrayList JavaDoc failedOnAllBackends = null;
1690      // List of controllers that have no more backends to execute queries
1691
ArrayList JavaDoc controllersWithoutBackends = null;
1692      SQLException JavaDoc exception = null;
1693
1694      // get a list that won't change while we go through it
1695
groupMembers = dvdb.getAllMembers();
1696      int size = groupMembers.size();
1697      boolean success = false;
1698      // Get the result of each controller
1699
for (int i = 0; i < size; i++)
1700      {
1701        Member member = (Member) groupMembers.get(i);
1702        if ((responses.getFailedMembers() != null)
1703            && responses.getFailedMembers().contains(member))
1704        {
1705          logger.warn("Controller " + member + " is suspected of failure.");
1706          continue;
1707        }
1708        Object JavaDoc r = responses.getResult(member);
1709        if (r instanceof Boolean JavaDoc)
1710        {
1711          if (((Boolean JavaDoc) r).booleanValue())
1712            success = true;
1713          else
1714            logger.error("Unexpected result for controller " + member);
1715        }
1716        else if (r instanceof NoMoreBackendException)
1717        {
1718          if (controllersWithoutBackends == null)
1719            controllersWithoutBackends = new ArrayList JavaDoc();
1720          controllersWithoutBackends.add(member);
1721          if (logger.isDebugEnabled())
1722            logger.debug("Controller " + member + " has no more backends to "
1723                + "release savepoint " + name + " from transaction "
1724                + transactionId + " (" + r + ")");
1725        }
1726        else if (r instanceof AllBackendsFailedException)
1727        {
1728          if (failedOnAllBackends == null)
1729            failedOnAllBackends = new ArrayList JavaDoc();
1730          failedOnAllBackends.add(member);
1731          if (logger.isDebugEnabled())
1732            logger.debug("release savepoint failed on all backends of "
1733                + "controller " + member + " (" + r + ")");
1734        }
1735        else if (r instanceof SQLException JavaDoc)
1736        {
1737          if (failedOnAllBackends == null)
1738            failedOnAllBackends = new ArrayList JavaDoc();
1739          failedOnAllBackends.add(member);
1740          String JavaDoc msg = "release savepoint " + name + " from transaction "
1741              + transactionId + " failed on controller " + member + " (" + r
1742              + ")";
1743          logger.warn(msg);
1744          exception = (SQLException JavaDoc) r;
1745        }
1746      }
1747
1748      // Notify all controllers where all backend failed (if any) that
1749
// completion was 'success'
1750
notifyRequestCompletion(releaseSavepointRequest, success, true,
1751          failedOnAllBackends);
1752
1753      // Notify controllers without active backends (if any)
1754
notifyRequestCompletion(releaseSavepointRequest, success, false,
1755          controllersWithoutBackends);
1756
1757      if (success)
1758        return; // This is a success if at least one controller has succeeded
1759

1760      if (exception != null)
1761        throw exception;
1762
1763      // At this point, all controllers failed
1764

1765      if (exception != null)
1766        throw exception;
1767      else
1768      {
1769        String JavaDoc msg = "Release savepoint " + name + " from transaction "
1770            + transactionId + " failed on all controllers";
1771        logger.warn(msg);
1772        throw new SQLException JavaDoc(msg);
1773      }
1774    }
1775    catch (SQLException JavaDoc e)
1776    {
1777      String JavaDoc msg = "Release savepoint " + name + " from transaction "
1778          + transactionId + " failed (" + e + ")";
1779      logger.warn(msg);
1780      throw e;
1781    }
1782  }
1783
1784}
Popular Tags