KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > requestmanager > distributed > RAIDb1DistributedRequestManager


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): Jean-Bernard van Zuylen.
23  */

24
25 package org.objectweb.cjdbc.controller.requestmanager.distributed;
26
27 import java.sql.SQLException JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30
31 import javax.management.NotCompliantMBeanException JavaDoc;
32
33 import org.objectweb.cjdbc.common.exceptions.NoMoreBackendException;
34 import org.objectweb.cjdbc.common.i18n.Translate;
35 import org.objectweb.cjdbc.common.sql.AbstractRequest;
36 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
37 import org.objectweb.cjdbc.common.sql.SelectRequest;
38 import org.objectweb.cjdbc.common.sql.StoredProcedure;
39 import org.objectweb.cjdbc.common.sql.UnknownRequest;
40 import org.objectweb.cjdbc.controller.cache.result.AbstractResultCache;
41 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer;
42 import org.objectweb.cjdbc.controller.loadbalancer.AllBackendsFailedException;
43 import org.objectweb.cjdbc.controller.recoverylog.RecoveryLog;
44 import org.objectweb.cjdbc.controller.requestmanager.TransactionMarkerMetaData;
45 import org.objectweb.cjdbc.controller.scheduler.AbstractScheduler;
46 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
47 import org.objectweb.cjdbc.controller.virtualdatabase.DistributedVirtualDatabase;
48 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.CJDBCGroupMessage;
49 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.Commit;
50 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecReadRequest;
51 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecReadStoredProcedure;
52 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecWriteRequest;
53 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecWriteRequestWithKeys;
54 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecWriteStoredProcedure;
55 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.NotifyCompletion;
56 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ReleaseSavepoint;
57 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.Rollback;
58 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.RollbackToSavepoint;
59 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.SetSavepoint;
60 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.UnlogCommit;
61 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.UnlogRequest;
62 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.UnlogRollback;
63 import org.objectweb.tribe.adapters.MulticastRequestAdapter;
64 import org.objectweb.tribe.adapters.MulticastResponse;
65 import org.objectweb.tribe.common.Member;
66
67 /**
68  * This class defines a RAIDb1DistributedRequestManager
69  *
70  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
71  * @author <a HREF="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen
72  * </a>
73  * @version 1.0
74  */

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

91   public RAIDb1DistributedRequestManager(DistributedVirtualDatabase vdb,
92       AbstractScheduler scheduler, AbstractResultCache cache,
93       AbstractLoadBalancer loadBalancer, RecoveryLog recoveryLog,
94       long beginTimeout, long commitTimeout, long rollbackTimeout)
95       throws SQLException JavaDoc, NotCompliantMBeanException JavaDoc
96   {
97     super(vdb, scheduler, cache, loadBalancer, recoveryLog, beginTimeout,
98         commitTimeout, rollbackTimeout);
99   }
100
101   /**
102    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#execRemoteReadRequest(org.objectweb.cjdbc.common.sql.SelectRequest)
103    */

104   public ControllerResultSet execRemoteReadRequest(SelectRequest request)
105       throws SQLException JavaDoc
106   {
107     try
108     {
109       // Iterate over controllers in members list (but us) until someone
110
// successfully executes our request.
111
Iterator JavaDoc i = dvdb.getAllMemberButUs().iterator();
112       while (i.hasNext())
113       {
114         Member controller = (Member) i.next();
115         ArrayList JavaDoc groupMembers = new ArrayList JavaDoc();
116         groupMembers.add(controller);
117
118         if (logger.isDebugEnabled())
119           logger.debug("Sending request "
120               + request.getSQLShortForm(dvdb.getSQLShortFormLength())
121               + (request.isAutoCommit() ? "" : " transaction "
122                   + request.getTransactionId()) + " to " + controller);
123
124         // Send query to remote controller
125
MulticastResponse responses;
126         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
127             groupMembers, new ExecReadRequest(request),
128             MulticastRequestAdapter.WAIT_ALL,
129             CJDBCGroupMessage.defaultCastTimeOut);
130
131         if (logger.isDebugEnabled())
132           logger.debug("Request "
133               + request.getSQLShortForm(dvdb.getSQLShortFormLength())
134               + " completed.");
135
136         Object JavaDoc ret = responses.getResult(controller);
137         if (ret instanceof ControllerResultSet)
138           return (ControllerResultSet) ret;
139       }
140
141       // No one answered, throw
142
throw new NoMoreBackendException();
143     }
144     catch (Exception JavaDoc e)
145     {
146       String JavaDoc msg = "An error occured while executing remote select request "
147           + request.getId();
148       logger.warn(msg, e);
149       throw new SQLException JavaDoc(msg + " (" + e + ")");
150     }
151   }
152
153   /**
154    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#execDistributedWriteRequest(org.objectweb.cjdbc.common.sql.AbstractWriteRequest)
155    */

156   public int execDistributedWriteRequest(AbstractWriteRequest request)
157       throws SQLException JavaDoc
158   {
159     try
160     {
161       int execWriteRequestResult = -1;
162
163       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
164
165       if (logger.isDebugEnabled())
166         logger.debug("Broadcasting request "
167             + request.getSQLShortForm(dvdb.getSQLShortFormLength())
168             + (request.isAutoCommit() ? "" : " transaction "
169                 + request.getTransactionId()) + " to all controllers ("
170             + dvdb.getChannel().getLocalMembership() + "->"
171             + groupMembers.toString() + ")");
172
173       // Send the query to everybody including us
174
MulticastResponse responses;
175       try
176       {
177         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
178             groupMembers, new ExecWriteRequest(request),
179             MulticastRequestAdapter.WAIT_ALL,
180             CJDBCGroupMessage.defaultCastTimeOut); // CHECK
181
// request.getTimeout());
182
}
183       catch (Exception JavaDoc e)
184       {
185         String JavaDoc msg = "An error occured while executing distributed write request "
186             + request.getId();
187         logger.warn(msg, e);
188         throw new SQLException JavaDoc(msg + " (" + e + ")");
189       }
190
191       if (logger.isDebugEnabled())
192         logger.debug("Request "
193             + request.getSQLShortForm(dvdb.getSQLShortFormLength())
194             + " completed.");
195
196       if (responses.getFailedMembers() != null)
197       { // Some controllers failed ... too bad !
198
logger.warn(responses.getFailedMembers().size()
199             + " controller(s) died during execution of request "
200             + request.getId());
201       }
202
203       // List of controllers that gave a AllBackendsFailedException
204
ArrayList JavaDoc failedOnAllBackends = null;
205       // List of controllers that have no more backends to execute queries
206
ArrayList JavaDoc controllersWithoutBackends = null;
207       SQLException JavaDoc exception = null;
208       int size = groupMembers.size();
209       // Get the result of each controller
210
for (int i = 0; i < size; i++)
211       {
212         Member member = (Member) groupMembers.get(i);
213         if ((responses.getFailedMembers() != null)
214             && responses.getFailedMembers().contains(member))
215         {
216           logger.warn("Controller " + member + " is suspected of failure.");
217           continue;
218         }
219         Object JavaDoc r = responses.getResult(member);
220         if (r instanceof Integer JavaDoc)
221         {
222           if (execWriteRequestResult == -1)
223             execWriteRequestResult = ((Integer JavaDoc) r).intValue();
224           else if (execWriteRequestResult != ((Integer JavaDoc) r).intValue())
225             logger.error("Controllers have different results for request "
226                 + request.getId());
227         }
228         else if (r instanceof AllBackendsFailedException)
229         {
230           if (failedOnAllBackends == null)
231             failedOnAllBackends = new ArrayList JavaDoc();
232           failedOnAllBackends.add(member);
233           if (logger.isDebugEnabled())
234             logger.debug("Request failed on all backends of controller "
235                 + member + " (" + r + ")");
236         }
237         else if (r instanceof NoMoreBackendException)
238         {
239           if (controllersWithoutBackends == null)
240             controllersWithoutBackends = new ArrayList JavaDoc();
241           controllersWithoutBackends.add(member);
242           if (logger.isDebugEnabled())
243             logger.debug("Controller " + member
244                 + " has no more backends to execute query (" + r + ")");
245         }
246         else if (r instanceof SQLException JavaDoc)
247         {
248           String JavaDoc msg = "Request " + request.getId() + " failed on controller "
249               + member + " (" + r + ")";
250           logger.warn(msg);
251           exception = (SQLException JavaDoc) r;
252         }
253       }
254
255       if (failedOnAllBackends != null)
256       { // Notify all controllers of completion
257
try
258         {
259           dvdb.getMulticastRequestAdapter().multicastMessage(
260               failedOnAllBackends,
261               new NotifyCompletion(request, execWriteRequestResult != -1),
262               MulticastRequestAdapter.WAIT_NONE,
263               CJDBCGroupMessage.defaultCastTimeOut); // CHECK
264
// request.getTimeout());
265
}
266         catch (Exception JavaDoc e)
267         {
268           String JavaDoc msg = "An error occured while notifying all controllers of failure of distributed write request "
269               + request.getId();
270           logger.warn(msg, e);
271           throw new SQLException JavaDoc(msg + " (" + e + ")");
272         }
273       }
274
275       if (execWriteRequestResult != -1)
276       {
277         if (logger.isDebugEnabled())
278           logger.debug("Request " + request.getId()
279               + " completed successfully.");
280         return execWriteRequestResult;
281       }
282
283       // At this point, all controllers failed
284

285       if (controllersWithoutBackends != null)
286       { // Notify all controllers without backend that have already logged the
287
// request that they must remove it from the log
288

289         int nbOfControllers = controllersWithoutBackends.size();
290         for (int i = 0; i < nbOfControllers; i++)
291         {
292           Member member = (Member) controllersWithoutBackends.get(i);
293           NoMoreBackendException nmbe = (NoMoreBackendException) responses
294               .getResult(member);
295           try
296           {
297             ArrayList JavaDoc dest = new ArrayList JavaDoc();
298             dest.add(member);
299             dvdb.getMulticastRequestAdapter().multicastMessage(dest,
300                 new UnlogRequest(request, nmbe.getRecoveryLogId()),
301                 MulticastRequestAdapter.WAIT_NONE,
302                 CJDBCGroupMessage.defaultCastTimeOut); // CHECK
303
// request.getTimeout());
304
}
305           catch (Exception JavaDoc e)
306           {
307             String JavaDoc msg = "An error occured while notifying controllers "
308                 + member + " to unlog failed distributed write request "
309                 + request.getId();
310             logger.error(msg, e);
311           }
312         }
313       }
314
315       if (exception != null)
316         throw exception;
317       else
318       {
319         String JavaDoc msg = "Request '" + request + "' failed on all controllers";
320         logger.warn(msg);
321         throw new SQLException JavaDoc(msg);
322       }
323     }
324     catch (SQLException JavaDoc e)
325     {
326       String JavaDoc msg = Translate
327           .get("loadbalancer.request.failed", new String JavaDoc[]{
328               request.getSQLShortForm(vdb.getSQLShortFormLength()),
329               e.getMessage()});
330       logger.warn(msg);
331       throw e;
332     }
333   }
334
335   /**
336    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#execDistributedWriteRequestWithKeys(org.objectweb.cjdbc.common.sql.AbstractWriteRequest)
337    */

338   public ControllerResultSet execDistributedWriteRequestWithKeys(
339       AbstractWriteRequest request) throws SQLException JavaDoc
340   {
341     try
342     {
343       ControllerResultSet execWriteRequestResult = null;
344
345       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
346
347       if (logger.isDebugEnabled())
348         logger.debug("Broadcasting request "
349             + request.getSQLShortForm(dvdb.getSQLShortFormLength())
350             + (request.isAutoCommit() ? "" : " transaction "
351                 + request.getTransactionId()) + ") to all controllers ("
352             + dvdb.getChannel().getLocalMembership() + "->"
353             + groupMembers.toString() + ")");
354
355       // Send the query to everybody including us
356
MulticastResponse responses;
357       try
358       {
359         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
360             groupMembers, new ExecWriteRequestWithKeys(request),
361             MulticastRequestAdapter.WAIT_ALL,
362             CJDBCGroupMessage.defaultCastTimeOut); // CHECK
363
// request.getTimeout());
364
}
365       catch (Exception JavaDoc e)
366       {
367         String JavaDoc msg = "An error occured while executing distributed write request with keys "
368             + request.getId();
369         logger.warn(msg, e);
370         throw new SQLException JavaDoc(msg + " (" + e + ")");
371       }
372
373       if (logger.isDebugEnabled())
374         logger.debug("Request "
375             + request.getSQLShortForm(dvdb.getSQLShortFormLength())
376             + " completed.");
377
378       if (responses.getFailedMembers() != null)
379       { // Some controllers failed ... too bad !
380
logger.warn(responses.getFailedMembers().size()
381             + " controller(s) died during execution of request "
382             + request.getId());
383       }
384
385       // List of controllers that gave a AllBackendsFailedException
386
ArrayList JavaDoc failedOnAllBackends = null;
387       // List of controllers that have no more backends to execute queries
388
ArrayList JavaDoc controllersWithoutBackends = null;
389       SQLException JavaDoc exception = null;
390       int size = groupMembers.size();
391       // Get the result of each controller
392
for (int i = 0; i < size; i++)
393       {
394         Member member = (Member) groupMembers.get(i);
395         if ((responses.getFailedMembers() != null)
396             && responses.getFailedMembers().contains(member))
397         {
398           logger.warn("Controller " + member + " is suspected of failure.");
399           continue;
400         }
401         Object JavaDoc r = responses.getResult(member);
402         if (r instanceof ControllerResultSet)
403         {
404           if (execWriteRequestResult == null)
405             execWriteRequestResult = (ControllerResultSet) r;
406         }
407         else if (r instanceof AllBackendsFailedException)
408         {
409           if (failedOnAllBackends == null)
410             failedOnAllBackends = new ArrayList JavaDoc();
411           failedOnAllBackends.add(member);
412           if (logger.isDebugEnabled())
413             logger.debug("Request failed on all backends of controller "
414                 + member + " (" + r + ")");
415         }
416         else if (r instanceof NoMoreBackendException)
417         {
418           if (controllersWithoutBackends == null)
419             controllersWithoutBackends = new ArrayList JavaDoc();
420           controllersWithoutBackends.add(member);
421           if (logger.isDebugEnabled())
422             logger.debug("Controller " + member
423                 + " has no more backends to execute query (" + r + ")");
424         }
425         else if (r instanceof SQLException JavaDoc)
426         {
427           String JavaDoc msg = "Request " + request.getId() + " failed on controller "
428               + member + " (" + r + ")";
429           logger.warn(msg);
430           exception = (SQLException JavaDoc) r;
431         }
432       }
433
434       if (failedOnAllBackends != null)
435       { // Notify all controllers of completion
436
try
437         {
438           dvdb.getMulticastRequestAdapter().multicastMessage(
439               failedOnAllBackends,
440               new NotifyCompletion(request, execWriteRequestResult != null),
441               MulticastRequestAdapter.WAIT_NONE,
442               CJDBCGroupMessage.defaultCastTimeOut); // CHECK
443
// request.getTimeout());
444
}
445         catch (Exception JavaDoc e)
446         {
447           String JavaDoc msg = "An error occured while notifying all controllers of failure of distributed write request with keys "
448               + request.getId();
449           logger.warn(msg, e);
450           throw new SQLException JavaDoc(msg + " (" + e + ")");
451         }
452       }
453
454       if (execWriteRequestResult != null)
455       {
456         if (logger.isDebugEnabled())
457           logger.debug("Request " + request.getId()
458               + " completed successfully.");
459         return execWriteRequestResult;
460       }
461
462       // At this point, all controllers failed
463

464       if (controllersWithoutBackends != null)
465       { // Notify all controllers without backend that have already logged the
466
// request that they must remove it from the log
467

468         int nbOfControllers = controllersWithoutBackends.size();
469         for (int i = 0; i < nbOfControllers; i++)
470         {
471           Member member = (Member) controllersWithoutBackends.get(i);
472           NoMoreBackendException nmbe = (NoMoreBackendException) responses
473               .getResult(member);
474           try
475           {
476             ArrayList JavaDoc dest = new ArrayList JavaDoc();
477             dest.add(member);
478             dvdb.getMulticastRequestAdapter().multicastMessage(dest,
479                 new UnlogRequest(request, nmbe.getRecoveryLogId()),
480                 MulticastRequestAdapter.WAIT_NONE,
481                 CJDBCGroupMessage.defaultCastTimeOut);
482           }
483           catch (Exception JavaDoc e)
484           {
485             String JavaDoc msg = "An error occured while notifying controllers "
486                 + member + " to unlog failed distributed write request "
487                 + request.getId();
488             logger.error(msg, e);
489           }
490         }
491       }
492
493       if (exception != null)
494         throw exception;
495       else
496       {
497         String JavaDoc msg = "Request '" + request + "' failed on all controllers";
498         logger.warn(msg);
499         throw new SQLException JavaDoc(msg);
500       }
501     }
502     catch (SQLException JavaDoc e)
503     {
504       String JavaDoc msg = Translate
505           .get("loadbalancer.request.failed", new String JavaDoc[]{
506               request.getSQLShortForm(vdb.getSQLShortFormLength()),
507               e.getMessage()});
508       logger.warn(msg);
509       throw e;
510     }
511   }
512
513   /**
514    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#execDistributedReadStoredProcedure(StoredProcedure)
515    */

516   public ControllerResultSet execDistributedReadStoredProcedure(
517       StoredProcedure proc) throws SQLException JavaDoc
518   {
519     try
520     {
521       ControllerResultSet result = null;
522
523       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
524
525       if (logger.isDebugEnabled())
526         logger.debug("Broadcasting read stored procedure "
527             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
528             + (proc.isAutoCommit() ? "" : " transaction "
529                 + proc.getTransactionId()) + ") to all controllers ("
530             + dvdb.getChannel().getLocalMembership() + "->"
531             + groupMembers.toString() + ")");
532
533       // Send the query to everybody including us
534
MulticastResponse responses;
535       try
536       {
537         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
538             groupMembers, new ExecReadStoredProcedure(proc),
539             MulticastRequestAdapter.WAIT_ALL,
540             CJDBCGroupMessage.defaultCastTimeOut); // CHECK proc.getTimeout());
541
}
542       catch (Exception JavaDoc e)
543       {
544         String JavaDoc msg = "An error occured while executing distributed read stored procedure "
545             + proc.getId();
546         logger.warn(msg, e);
547         throw new SQLException JavaDoc(msg + " (" + e + ")");
548       }
549
550       if (logger.isDebugEnabled())
551         logger.debug("Stored procedure "
552             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
553             + " completed.");
554
555       if (responses.getFailedMembers() != null)
556       { // Some controllers failed ... too bad !
557
logger.warn(responses.getFailedMembers().size()
558             + " controller(s) died during execution of stored procedure "
559             + proc.getId());
560       }
561
562       // List of controllers that gave a AllBackendsFailedException
563
ArrayList JavaDoc failedOnAllBackends = null;
564       // List of controllers that have no more backends to execute queries
565
ArrayList JavaDoc controllersWithoutBackends = null;
566       SQLException JavaDoc exception = null;
567       int size = groupMembers.size();
568       // Get the result of each controller
569
for (int i = 0; i < size; i++)
570       {
571         Member member = (Member) groupMembers.get(i);
572         if ((responses.getFailedMembers() != null)
573             && responses.getFailedMembers().contains(member))
574         {
575           logger.warn("Controller " + member + " is suspected of failure.");
576           continue;
577         }
578         Object JavaDoc r = responses.getResult(member);
579         if (r instanceof ControllerResultSet)
580         {
581           if (result == null)
582             result = (ControllerResultSet) r;
583         }
584         else if (r instanceof AllBackendsFailedException)
585         {
586           if (failedOnAllBackends == null)
587             failedOnAllBackends = new ArrayList JavaDoc();
588           failedOnAllBackends.add(member);
589         }
590         else if (r instanceof NoMoreBackendException)
591         {
592           if (controllersWithoutBackends == null)
593             controllersWithoutBackends = new ArrayList JavaDoc();
594           controllersWithoutBackends.add(member);
595           if (logger.isDebugEnabled())
596             logger.debug("Controller " + member
597                 + " has no more backends to execute query (" + r + ")");
598         }
599         else if (r instanceof SQLException JavaDoc)
600         {
601           String JavaDoc msg = "Stored procedure " + proc.getId()
602               + " failed on controller " + member + " (" + r + ")";
603           logger.warn(msg);
604           exception = (SQLException JavaDoc) r;
605         }
606       }
607
608       if (failedOnAllBackends != null)
609       { // Notify all controllers of completion
610
try
611         {
612           dvdb.getMulticastRequestAdapter().multicastMessage(
613               failedOnAllBackends, new NotifyCompletion(proc, result != null),
614               MulticastRequestAdapter.WAIT_NONE,
615               CJDBCGroupMessage.defaultCastTimeOut); // CHECK
616
// proc.getTimeout());
617
}
618         catch (Exception JavaDoc e)
619         {
620           String JavaDoc msg = "An error occured while notifying all controllers of failure of read stored procedure "
621               + proc.getId();
622           logger.warn(msg, e);
623           throw new SQLException JavaDoc(msg + " (" + e + ")");
624         }
625       }
626
627       if (result != null)
628       {
629         if (logger.isDebugEnabled())
630           logger.debug("Stored procedure " + proc.getId()
631               + " completed successfully.");
632         return result; // Success
633
}
634
635       // At this point, all controllers failed
636

637       if (controllersWithoutBackends != null)
638       { // Notify all controllers without backend that have already logged the
639
// request that they must remove it from the log
640

641         int nbOfControllers = controllersWithoutBackends.size();
642         for (int i = 0; i < nbOfControllers; i++)
643         {
644           Member member = (Member) controllersWithoutBackends.get(i);
645           NoMoreBackendException nmbe = (NoMoreBackendException) responses
646               .getResult(member);
647           try
648           {
649             ArrayList JavaDoc dest = new ArrayList JavaDoc();
650             dest.add(member);
651             dvdb.getMulticastRequestAdapter().multicastMessage(dest,
652                 new UnlogRequest(proc, nmbe.getRecoveryLogId()),
653                 MulticastRequestAdapter.WAIT_NONE,
654                 CJDBCGroupMessage.defaultCastTimeOut); // CHECK
655
// proc.getTimeout());
656
}
657           catch (Exception JavaDoc e)
658           {
659             String JavaDoc msg = "An error occured while notifying controllers "
660                 + member
661                 + " to unlog failed distributed read stored procedure "
662                 + proc.getId();
663             logger.error(msg, e);
664           }
665         }
666       }
667
668       if (exception != null)
669         throw exception;
670       else
671       {
672         String JavaDoc msg = "Stored procedure '" + proc
673             + "' failed on all controllers";
674         logger.warn(msg);
675         throw new SQLException JavaDoc(msg);
676       }
677     }
678     catch (SQLException JavaDoc e)
679     {
680       String JavaDoc msg = Translate.get("loadbalancer.request.failed", new String JavaDoc[]{
681           proc.getSQLShortForm(vdb.getSQLShortFormLength()), e.getMessage()});
682       logger.warn(msg);
683       throw e;
684     }
685   }
686
687   /**
688    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#execDistributedWriteStoredProcedure(org.objectweb.cjdbc.common.sql.StoredProcedure)
689    */

690   public int execDistributedWriteStoredProcedure(StoredProcedure proc)
691       throws SQLException JavaDoc
692   {
693     try
694     {
695       int execWriteStoredProcedureResult = NO_RESULT;
696
697       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
698
699       if (logger.isDebugEnabled())
700         logger.debug("Broadcasting write store procedure "
701             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
702             + (proc.isAutoCommit() ? "" : " transaction "
703                 + proc.getTransactionId()) + ") to all controllers ("
704             + dvdb.getChannel().getLocalMembership() + "->"
705             + groupMembers.toString() + ")");
706
707       // Send the query to everybody including us
708
MulticastResponse responses;
709       try
710       {
711         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
712             groupMembers, new ExecWriteStoredProcedure(proc),
713             MulticastRequestAdapter.WAIT_ALL,
714             CJDBCGroupMessage.defaultCastTimeOut); // CHECK proc.getTimeout());
715
}
716       catch (Exception JavaDoc e)
717       {
718         String JavaDoc msg = "An error occured while executing distributed write stored procedure "
719             + proc.getId();
720         logger.warn(msg, e);
721         throw new SQLException JavaDoc(msg + " (" + e + ")");
722       }
723
724       if (logger.isDebugEnabled())
725         logger.debug("Stored procedure "
726             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
727             + " completed.");
728
729       if (responses.getFailedMembers() != null)
730       { // Some controllers failed ... too bad !
731
logger.warn(responses.getFailedMembers().size()
732             + " controller(s) died during execution of stored procedure "
733             + proc.getId());
734       }
735
736       // List of controllers that gave a AllBackendsFailedException
737
ArrayList JavaDoc failedOnAllBackends = null;
738       // List of controllers that have no more backends to execute queries
739
ArrayList JavaDoc controllersWithoutBackends = null;
740       SQLException JavaDoc exception = null;
741       int size = groupMembers.size();
742       // Get the result of each controller
743
for (int i = 0; i < size; i++)
744       {
745         Member member = (Member) groupMembers.get(i);
746         if ((responses.getFailedMembers() != null)
747             && responses.getFailedMembers().contains(member))
748         {
749           logger.warn("Controller " + member + " is suspected of failure.");
750           continue;
751         }
752         Object JavaDoc r = responses.getResult(member);
753         if (r instanceof Integer JavaDoc)
754         {
755           if (execWriteStoredProcedureResult == NO_RESULT)
756             execWriteStoredProcedureResult = ((Integer JavaDoc) r).intValue();
757         }
758         else if (r instanceof AllBackendsFailedException)
759         {
760           if (failedOnAllBackends == null)
761             failedOnAllBackends = new ArrayList JavaDoc();
762           failedOnAllBackends.add(member);
763         }
764         else if (r instanceof NoMoreBackendException)
765         {
766           if (controllersWithoutBackends == null)
767             controllersWithoutBackends = new ArrayList JavaDoc();
768           controllersWithoutBackends.add(member);
769           if (logger.isDebugEnabled())
770             logger.debug("Controller " + member
771                 + " has no more backends to execute query (" + r + ")");
772         }
773         else if (r instanceof SQLException JavaDoc)
774         {
775           String JavaDoc msg = "Stored procedure " + proc.getId()
776               + " failed on controller " + member + " (" + r + ")";
777           logger.warn(msg);
778           exception = (SQLException JavaDoc) r;
779         }
780       }
781
782       if (failedOnAllBackends != null)
783       { // Notify all controllers of completion
784
try
785         {
786           dvdb.getMulticastRequestAdapter().multicastMessage(
787               failedOnAllBackends,
788               new NotifyCompletion(proc,
789                   execWriteStoredProcedureResult != NO_RESULT),
790               MulticastRequestAdapter.WAIT_NONE,
791               CJDBCGroupMessage.defaultCastTimeOut); // CHECK
792
// proc.getTimeout());
793
}
794         catch (Exception JavaDoc e)
795         {
796           String JavaDoc msg = "An error occured while notifying all controllers of failure of write stored procedure "
797               + proc.getId();
798           logger.warn(msg, e);
799           throw new SQLException JavaDoc(msg + " (" + e + ")");
800         }
801       }
802
803       if (execWriteStoredProcedureResult != NO_RESULT)
804       {
805         if (logger.isDebugEnabled())
806           logger.debug("Stored procedure " + proc.getId()
807               + " completed successfully.");
808         return execWriteStoredProcedureResult; // Success
809
}
810
811       // At this point, all controllers failed
812

813       if (controllersWithoutBackends != null)
814       { // Notify all controllers without backend that have already logged the
815
// request that they must remove it from the log
816

817         int nbOfControllers = controllersWithoutBackends.size();
818         for (int i = 0; i < nbOfControllers; i++)
819         {
820           Member member = (Member) controllersWithoutBackends.get(i);
821           NoMoreBackendException nmbe = (NoMoreBackendException) responses
822               .getResult(member);
823           try
824           {
825             ArrayList JavaDoc dest = new ArrayList JavaDoc();
826             dest.add(member);
827             dvdb.getMulticastRequestAdapter().multicastMessage(dest,
828                 new UnlogRequest(proc, nmbe.getRecoveryLogId()),
829                 MulticastRequestAdapter.WAIT_NONE,
830                 CJDBCGroupMessage.defaultCastTimeOut); // CHECK
831
// proc.getTimeout());
832
}
833           catch (Exception JavaDoc e)
834           {
835             String JavaDoc msg = "An error occured while notifying controllers "
836                 + member
837                 + " to unlog failed distributed write stored procedure "
838                 + proc.getId();
839             logger.error(msg, e);
840           }
841         }
842       }
843
844       if (exception != null)
845         throw exception;
846       else
847       {
848         String JavaDoc msg = "Stored procedure '" + proc
849             + "' failed on all controllers";
850         logger.warn(msg);
851         throw new SQLException JavaDoc(msg);
852       }
853     }
854     catch (SQLException JavaDoc e)
855     {
856       String JavaDoc msg = Translate.get("loadbalancer.request.failed", new String JavaDoc[]{
857           proc.getSQLShortForm(vdb.getSQLShortFormLength()), e.getMessage()});
858       logger.warn(msg);
859       throw e;
860     }
861   }
862
863   /**
864    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedCommit(String,
865    * long)
866    */

867   public void distributedCommit(String JavaDoc login, long transactionId)
868       throws SQLException JavaDoc
869   {
870     try
871     {
872       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
873       if (logger.isDebugEnabled())
874         logger.debug("Broadcasting transaction " + transactionId
875             + " commit to all controllers ("
876             + dvdb.getChannel().getLocalMembership() + "->"
877             + groupMembers.toString() + ")");
878
879       // Send the query to everybody including us
880
MulticastResponse responses;
881       try
882       {
883         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
884             groupMembers, new Commit(login, transactionId),
885             MulticastRequestAdapter.WAIT_ALL,
886             CJDBCGroupMessage.defaultCastTimeOut); // CHECK this.commitTimeout
887
}
888       catch (Exception JavaDoc e)
889       {
890         String JavaDoc msg = "An error occured while executing distributed rollback for transaction "
891             + transactionId;
892         logger.warn(msg, e);
893         throw new SQLException JavaDoc(msg + "(" + e + ")");
894       }
895
896       if (logger.isDebugEnabled())
897         logger.debug("Commit of transaction " + transactionId + " completed.");
898
899       if (responses.getFailedMembers() != null)
900       { // Some controllers failed ... too bad !
901
logger.warn(responses.getFailedMembers().size()
902             + " controller(s) died during execution of commit for transaction "
903             + transactionId);
904       }
905
906       // List of controllers that gave a AllBackendsFailedException
907
ArrayList JavaDoc failedOnAllBackends = null;
908       // List of controllers that have no more backends to execute queries
909
ArrayList JavaDoc controllersWithoutBackends = null;
910       SQLException JavaDoc exception = null;
911       int size = groupMembers.size();
912       boolean success = false;
913       // Get the result of each controller
914
for (int i = 0; i < size; i++)
915       {
916         Member member = (Member) groupMembers.get(i);
917         if ((responses.getFailedMembers() != null)
918             && responses.getFailedMembers().contains(member))
919         {
920           logger.warn("Controller " + member + " is suspected of failure.");
921           continue;
922         }
923         Object JavaDoc r = responses.getResult(member);
924         if (r instanceof Boolean JavaDoc)
925         {
926           if (((Boolean JavaDoc) r).booleanValue())
927             success = true;
928           else
929             logger.error("Unexpected result for controller " + member);
930         }
931         else if (r instanceof NoMoreBackendException)
932         {
933           if (controllersWithoutBackends == null)
934             controllersWithoutBackends = new ArrayList JavaDoc();
935           controllersWithoutBackends.add(member);
936           if (logger.isDebugEnabled())
937             logger.debug("Controller " + member
938                 + " has no more backends to commit transaction "
939                 + transactionId + " (" + r + ")");
940         }
941         else if (r instanceof AllBackendsFailedException)
942         {
943           if (failedOnAllBackends == null)
944             failedOnAllBackends = new ArrayList JavaDoc();
945           failedOnAllBackends.add(member);
946           if (logger.isDebugEnabled())
947             logger.debug("Commit failed on all backends of controller "
948                 + member + " (" + r + ")");
949         }
950         else if (r instanceof SQLException JavaDoc)
951         {
952           String JavaDoc msg = "Commit of transaction " + transactionId
953               + " failed on controller " + member + " (" + r + ")";
954           logger.warn(msg);
955           exception = (SQLException JavaDoc) r;
956         }
957       }
958
959       if (failedOnAllBackends != null)
960       { // Notify all controllers where all backend failed that the commit
961
// completed with 'success'
962
AbstractRequest request = new UnknownRequest("commit", false, 0, "\n");
963         request.setTransactionId(transactionId);
964         try
965         {
966           dvdb.getMulticastRequestAdapter().multicastMessage(
967               failedOnAllBackends, new NotifyCompletion(request, success),
968               MulticastRequestAdapter.WAIT_NONE,
969               CJDBCGroupMessage.defaultCastTimeOut); // CHECK commitTimeout);
970
}
971         catch (Exception JavaDoc e)
972         {
973           String JavaDoc msg = "An error occured while notifying all controllers of failure to commit transaction "
974               + transactionId;
975           logger.warn(msg, e);
976           throw new SQLException JavaDoc(msg + " (" + e + ")");
977         }
978       }
979
980       if (success)
981         return; // This is a success if at least one controller has succeeded
982

983       // At this point, all controllers failed
984

985       if (controllersWithoutBackends != null)
986       { // Notify all controllers without backend that have already logged the
987
// request that they must remove it from the log
988

989         int nbOfControllers = controllersWithoutBackends.size();
990         for (int i = 0; i < nbOfControllers; i++)
991         {
992           Member member = (Member) controllersWithoutBackends.get(i);
993           NoMoreBackendException nmbe = (NoMoreBackendException) responses
994               .getResult(member);
995           try
996           {
997             ArrayList JavaDoc dest = new ArrayList JavaDoc();
998             dest.add(member);
999             // Here we use the commit timeout field to transport the recovery
1000
// log id. This is ugly but convenient.
1001
dvdb.getMulticastRequestAdapter().multicastMessage(
1002                dest,
1003                new UnlogCommit(new TransactionMarkerMetaData(transactionId,
1004                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1005                MulticastRequestAdapter.WAIT_NONE,
1006                CJDBCGroupMessage.defaultCastTimeOut); // CHECK
1007
// this.commitTimeout);
1008
}
1009          catch (Exception JavaDoc e)
1010          {
1011            String JavaDoc msg = "An error occured while notifying controllers "
1012                + member + " to unlog failed commit for transaction "
1013                + transactionId;
1014            logger.error(msg, e);
1015          }
1016        }
1017      }
1018
1019      if (exception != null)
1020        throw exception;
1021      else
1022      {
1023        String JavaDoc msg = "Transaction " + transactionId
1024            + " failed to commit on all controllers";
1025        logger.warn(msg);
1026        throw new SQLException JavaDoc(msg);
1027      }
1028    }
1029    catch (SQLException JavaDoc e)
1030    {
1031      String JavaDoc msg = "Transaction " + transactionId + " commit failed (" + e
1032          + ")";
1033      logger.warn(msg);
1034      throw e;
1035    }
1036  }
1037
1038  /**
1039   * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedRollback(String,
1040   * long)
1041   */

1042  public void distributedRollback(String JavaDoc login, long transactionId)
1043      throws SQLException JavaDoc
1044  {
1045    try
1046    {
1047      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1048      if (logger.isDebugEnabled())
1049        logger.debug("Broadcasting transaction " + transactionId
1050            + " rollback to all controllers ("
1051            + dvdb.getChannel().getLocalMembership() + "->"
1052            + groupMembers.toString() + ")");
1053
1054      // Send the query to everybody including us
1055
MulticastResponse responses;
1056      try
1057      {
1058        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1059            groupMembers, new Rollback(login, transactionId),
1060            MulticastRequestAdapter.WAIT_ALL,
1061            CJDBCGroupMessage.defaultCastTimeOut); // CHECK
1062
// this.rollbackTimeout);
1063
}
1064      catch (Exception JavaDoc e)
1065      {
1066        String JavaDoc msg = "An error occured while executing distributed rollback for transaction "
1067            + transactionId;
1068        logger.warn(msg, e);
1069        throw new SQLException JavaDoc(msg + "(" + e + ")");
1070      }
1071
1072      if (logger.isDebugEnabled())
1073        logger
1074            .debug("rollback of transaction " + transactionId + " completed.");
1075
1076      if (responses.getFailedMembers() != null)
1077      { // Some controllers failed ... too bad !
1078
logger
1079            .warn(responses.getFailedMembers().size()
1080                + " controller(s) died during execution of rollback for transaction "
1081                + transactionId);
1082      }
1083
1084      // List of controllers that gave a AllBackendsFailedException
1085
ArrayList JavaDoc failedOnAllBackends = null;
1086      // List of controllers that have no more backends to execute queries
1087
ArrayList JavaDoc controllersWithoutBackends = null;
1088      SQLException JavaDoc exception = null;
1089      int size = groupMembers.size();
1090      boolean success = false;
1091      // Get the result of each controller
1092
for (int i = 0; i < size; i++)
1093      {
1094        Member member = (Member) groupMembers.get(i);
1095        if ((responses.getFailedMembers() != null)
1096            && responses.getFailedMembers().contains(member))
1097        {
1098          logger.warn("Controller " + member + " is suspected of failure.");
1099          continue;
1100        }
1101        Object JavaDoc r = responses.getResult(member);
1102        if (r instanceof Boolean JavaDoc)
1103        {
1104          if (((Boolean JavaDoc) r).booleanValue())
1105            success = true;
1106          else
1107            logger.error("Unexpected result for controller " + member);
1108        }
1109        else if (r instanceof NoMoreBackendException)
1110        {
1111          if (controllersWithoutBackends == null)
1112            controllersWithoutBackends = new ArrayList JavaDoc();
1113          controllersWithoutBackends.add(member);
1114          if (logger.isDebugEnabled())
1115            logger.debug("Controller " + member
1116                + " has no more backends to rollback transaction "
1117                + transactionId + " (" + r + ")");
1118        }
1119        else if (r instanceof AllBackendsFailedException)
1120        {
1121          if (failedOnAllBackends == null)
1122            failedOnAllBackends = new ArrayList JavaDoc();
1123          failedOnAllBackends.add(member);
1124          if (logger.isDebugEnabled())
1125            logger.debug("rollback failed on all backends of controller "
1126                + member + " (" + r + ")");
1127        }
1128        else if (r instanceof SQLException JavaDoc)
1129        {
1130          String JavaDoc msg = "rollback of transaction " + transactionId
1131              + " failed on controller " + member + " (" + r + ")";
1132          logger.warn(msg);
1133          exception = (SQLException JavaDoc) r;
1134        }
1135      }
1136
1137      if (failedOnAllBackends != null)
1138      { // Notify all controllers where all backend failed that the rollback
1139
// completed with 'success'
1140
AbstractRequest request = new UnknownRequest("rollback", false, 0, "\n");
1141        request.setTransactionId(transactionId);
1142        try
1143        {
1144          dvdb.getMulticastRequestAdapter().multicastMessage(
1145              failedOnAllBackends, new NotifyCompletion(request, success),
1146              MulticastRequestAdapter.WAIT_NONE,
1147              CJDBCGroupMessage.defaultCastTimeOut); // CHECK rollbackTimeout);
1148
}
1149        catch (Exception JavaDoc e)
1150        {
1151          String JavaDoc msg = "An error occured while notifying all controllers of failure to rollback transaction "
1152              + transactionId;
1153          logger.warn(msg, e);
1154          throw new SQLException JavaDoc(msg + " (" + e + ")");
1155        }
1156      }
1157
1158      if (success)
1159        return; // This is a success if at least one controller has succeeded
1160

1161      if (exception != null)
1162        throw exception;
1163
1164      // At this point, all controllers failed
1165

1166      if (controllersWithoutBackends != null)
1167      { // Notify all controllers without backend that have already logged the
1168
// request that they must remove it from the log
1169

1170        int nbOfControllers = controllersWithoutBackends.size();
1171        for (int i = 0; i < nbOfControllers; i++)
1172        {
1173          Member member = (Member) controllersWithoutBackends.get(i);
1174          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1175              .getResult(member);
1176          try
1177          {
1178            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1179            dest.add(member);
1180            // Here we use the commit timeout field to transport the recovery
1181
// log id. This is ugly but convenient.
1182
dvdb.getMulticastRequestAdapter().multicastMessage(
1183                dest,
1184                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1185                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1186                MulticastRequestAdapter.WAIT_NONE,
1187                CJDBCGroupMessage.defaultCastTimeOut); // CHECK
1188
// this.commitTimeout);
1189
}
1190          catch (Exception JavaDoc e)
1191          {
1192            String JavaDoc msg = "An error occured while notifying controllers "
1193                + member + " to unlog failed rollback for transaction "
1194                + transactionId;
1195            logger.error(msg, e);
1196          }
1197        }
1198      }
1199
1200      if (exception != null)
1201        throw exception;
1202      else
1203      {
1204        String JavaDoc msg = "Transaction " + transactionId
1205            + " failed to rollback on all controllers";
1206        logger.warn(msg);
1207        throw new SQLException JavaDoc(msg);
1208      }
1209    }
1210    catch (SQLException JavaDoc e)
1211    {
1212      String JavaDoc msg = "Transaction " + transactionId + " rollback failed (" + e
1213          + ")";
1214      logger.warn(msg);
1215      throw e;
1216    }
1217  }
1218
1219  /**
1220   * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedRollback(long,
1221   * String)
1222   */

1223  public void distributedRollback(long transactionId, String JavaDoc savepointName)
1224      throws SQLException JavaDoc
1225  {
1226    try
1227    {
1228      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1229      if (logger.isDebugEnabled())
1230        logger.debug("Broadcasting rollback to savepoint " + savepointName
1231            + " for transaction " + transactionId + " to all controllers ("
1232            + dvdb.getChannel().getLocalMembership() + "->"
1233            + groupMembers.toString() + ")");
1234
1235      // Send the query to everybody including us
1236
MulticastResponse responses;
1237      try
1238      {
1239        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1240            groupMembers,
1241            new RollbackToSavepoint(transactionId, savepointName),
1242            MulticastRequestAdapter.WAIT_ALL,
1243            CJDBCGroupMessage.defaultCastTimeOut);
1244      }
1245      catch (Exception JavaDoc e)
1246      {
1247        String JavaDoc msg = "An error occured while executing distributed rollback to"
1248            + " savepoint " + savepointName + " for transaction "
1249            + transactionId;
1250        logger.warn(msg, e);
1251        throw new SQLException JavaDoc(msg + "(" + e + ")");
1252      }
1253
1254      if (logger.isDebugEnabled())
1255        logger.debug("rollback to savepoint " + savepointName + " for "
1256            + "transaction " + transactionId + " completed.");
1257
1258      if (responses.getFailedMembers() != null)
1259      { // Some controllers failed ... too bad !
1260
logger.warn(responses.getFailedMembers().size() + " controller(s) died"
1261            + " during execution of rollback to savepoint " + savepointName
1262            + " for transaction " + transactionId);
1263      }
1264
1265      // List of controllers that gave a AllBackendsFailedException
1266
ArrayList JavaDoc failedOnAllBackends = null;
1267      // List of controllers that have no more backends to execute queries
1268
ArrayList JavaDoc controllersWithoutBackends = null;
1269      SQLException JavaDoc exception = null;
1270      int size = groupMembers.size();
1271      boolean success = false;
1272      // Get the result of each controller
1273
for (int i = 0; i < size; i++)
1274      {
1275        Member member = (Member) groupMembers.get(i);
1276        if ((responses.getFailedMembers() != null)
1277            && responses.getFailedMembers().contains(member))
1278        {
1279          logger.warn("Controller " + member + " is suspected of failure.");
1280          continue;
1281        }
1282        Object JavaDoc r = responses.getResult(member);
1283        if (r instanceof Boolean JavaDoc)
1284        {
1285          if (((Boolean JavaDoc) r).booleanValue())
1286            success = true;
1287          else
1288            logger.error("Unexpected result for controller " + member);
1289        }
1290        else if (r instanceof NoMoreBackendException)
1291        {
1292          if (controllersWithoutBackends == null)
1293            controllersWithoutBackends = new ArrayList JavaDoc();
1294          controllersWithoutBackends.add(member);
1295          if (logger.isDebugEnabled())
1296            logger.debug("Controller " + member + " has no more backends to "
1297                + "rollback to savepoint " + savepointName + " for "
1298                + "transaction " + transactionId + " (" + r + ")");
1299        }
1300        else if (r instanceof AllBackendsFailedException)
1301        {
1302          if (failedOnAllBackends == null)
1303            failedOnAllBackends = new ArrayList JavaDoc();
1304          failedOnAllBackends.add(member);
1305          if (logger.isDebugEnabled())
1306            logger.debug("rollback to savepoint failed on all backends of "
1307                + "controller " + member + " (" + r + ")");
1308        }
1309        else if (r instanceof SQLException JavaDoc)
1310        {
1311          String JavaDoc msg = "rollback to savepoint " + savepointName + " for "
1312              + "transaction " + transactionId + " failed on controller "
1313              + member + " (" + r + ")";
1314          logger.warn(msg);
1315          exception = (SQLException JavaDoc) r;
1316        }
1317      }
1318
1319      if (failedOnAllBackends != null)
1320      { // Notify all controllers where all backend failed that the rollback
1321
// completed with 'success'
1322
AbstractRequest request = new UnknownRequest("rollback "
1323            + savepointName, false, 0, "\n");
1324        request.setTransactionId(transactionId);
1325        try
1326        {
1327          dvdb.getMulticastRequestAdapter().multicastMessage(
1328              failedOnAllBackends, new NotifyCompletion(request, success),
1329              MulticastRequestAdapter.WAIT_NONE,
1330              CJDBCGroupMessage.defaultCastTimeOut);
1331        }
1332        catch (Exception JavaDoc e)
1333        {
1334          String JavaDoc msg = "An error occured while notifying all controllers of "
1335              + "failure to rollback to savepoint " + savepointName + " for "
1336              + "transaction " + transactionId;
1337          logger.warn(msg, e);
1338          throw new SQLException JavaDoc(msg + " (" + e + ")");
1339        }
1340      }
1341
1342      if (success)
1343        return; // This is a success if at least one controller has succeeded
1344

1345      if (exception != null)
1346        throw exception;
1347
1348      // At this point, all controllers failed
1349

1350      if (controllersWithoutBackends != null)
1351      { // Notify all controllers without backend that have already logged the
1352
// request that they must remove it from the log
1353
int nbOfControllers = controllersWithoutBackends.size();
1354        for (int i = 0; i < nbOfControllers; i++)
1355        {
1356          Member member = (Member) controllersWithoutBackends.get(i);
1357          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1358              .getResult(member);
1359          try
1360          {
1361            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1362            dest.add(member);
1363            // Here we use the commit timeout field to transport the recovery
1364
// log id. This is ugly but convenient.
1365
dvdb.getMulticastRequestAdapter().multicastMessage(
1366                dest,
1367                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1368                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1369                MulticastRequestAdapter.WAIT_NONE,
1370                CJDBCGroupMessage.defaultCastTimeOut);
1371          }
1372          catch (Exception JavaDoc e)
1373          {
1374            String JavaDoc msg = "An error occured while notifying controllers "
1375                + member + " to unlog failed rollback to savepoint "
1376                + savepointName + " for transaction " + transactionId;
1377            logger.error(msg, e);
1378          }
1379        }
1380      }
1381
1382      if (exception != null)
1383        throw exception;
1384      else
1385      {
1386        String JavaDoc msg = "Rollback to savepoint " + savepointName + " for "
1387            + "transaction " + transactionId + " failed on all controllers";
1388        logger.warn(msg);
1389        throw new SQLException JavaDoc(msg);
1390      }
1391    }
1392    catch (SQLException JavaDoc e)
1393    {
1394      String JavaDoc msg = "Rollback to savepoint " + savepointName + " for "
1395          + "transaction " + transactionId + " failed (" + e + ")";
1396      logger.warn(msg);
1397      throw e;
1398    }
1399  }
1400
1401  /**
1402   * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedSetSavepoint(long,
1403   * String)
1404   */

1405  public void distributedSetSavepoint(long transactionId, String JavaDoc name)
1406      throws SQLException JavaDoc
1407  {
1408    try
1409    {
1410      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1411      if (logger.isDebugEnabled())
1412        logger.debug("Broadcasting set savepoint " + name + " to transaction "
1413            + transactionId + " to all controllers ("
1414            + dvdb.getChannel().getLocalMembership() + "->"
1415            + groupMembers.toString() + ")");
1416
1417      // Send the query to everybody including us
1418
MulticastResponse responses;
1419      try
1420      {
1421        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1422            groupMembers, new SetSavepoint(transactionId, name),
1423            MulticastRequestAdapter.WAIT_ALL,
1424            CJDBCGroupMessage.defaultCastTimeOut);
1425      }
1426      catch (Exception JavaDoc e)
1427      {
1428        String JavaDoc msg = "An error occured while executing distributed set "
1429            + "savepoint " + name + " to transaction " + transactionId;
1430        logger.warn(msg, e);
1431        throw new SQLException JavaDoc(msg + "(" + e + ")");
1432      }
1433
1434      if (logger.isDebugEnabled())
1435        logger.debug("set savepoint " + name + " to transaction "
1436            + transactionId + " completed.");
1437
1438      if (responses.getFailedMembers() != null)
1439      { // Some controllers failed ... too bad !
1440
logger.warn(responses.getFailedMembers().size() + " controller(s) died"
1441            + " during execution of set savepoint " + name + " to transaction "
1442            + transactionId);
1443      }
1444
1445      // List of controllers that gave a AllBackendsFailedException
1446
ArrayList JavaDoc failedOnAllBackends = null;
1447      // List of controllers that have no more backends to execute queries
1448
ArrayList JavaDoc controllersWithoutBackends = null;
1449      SQLException JavaDoc exception = null;
1450      int size = groupMembers.size();
1451      boolean success = false;
1452      // Get the result of each controller
1453
for (int i = 0; i < size; i++)
1454      {
1455        Member member = (Member) groupMembers.get(i);
1456        if ((responses.getFailedMembers() != null)
1457            && responses.getFailedMembers().contains(member))
1458        {
1459          logger.warn("Controller " + member + " is suspected of failure.");
1460          continue;
1461        }
1462        Object JavaDoc r = responses.getResult(member);
1463        if (r instanceof Boolean JavaDoc)
1464        {
1465          if (((Boolean JavaDoc) r).booleanValue())
1466            success = true;
1467          else
1468            logger.error("Unexpected result for controller " + member);
1469        }
1470        else if (r instanceof NoMoreBackendException)
1471        {
1472          if (controllersWithoutBackends == null)
1473            controllersWithoutBackends = new ArrayList JavaDoc();
1474          controllersWithoutBackends.add(member);
1475          if (logger.isDebugEnabled())
1476            logger.debug("Controller " + member + " has no more backends to "
1477                + "set savepoint " + name + " to transaction " + transactionId
1478                + " (" + r + ")");
1479        }
1480        else if (r instanceof AllBackendsFailedException)
1481        {
1482          if (failedOnAllBackends == null)
1483            failedOnAllBackends = new ArrayList JavaDoc();
1484          failedOnAllBackends.add(member);
1485          if (logger.isDebugEnabled())
1486            logger.debug("set savepoint failed on all backends of controller "
1487                + member + " (" + r + ")");
1488        }
1489        else if (r instanceof SQLException JavaDoc)
1490        {
1491          String JavaDoc msg = "set savepoint " + name + " to transaction "
1492              + transactionId + " failed on controller " + member + " (" + r
1493              + ")";
1494          logger.warn(msg);
1495          exception = (SQLException JavaDoc) r;
1496        }
1497      }
1498
1499      if (failedOnAllBackends != null)
1500      { // Notify all controllers where all backend failed that the rollback
1501
// completed with 'success'
1502
AbstractRequest request = new UnknownRequest("savepoint " + name,
1503            false, 0, "\n");
1504        request.setTransactionId(transactionId);
1505        try
1506        {
1507          dvdb.getMulticastRequestAdapter().multicastMessage(
1508              failedOnAllBackends, new NotifyCompletion(request, success),
1509              MulticastRequestAdapter.WAIT_NONE,
1510              CJDBCGroupMessage.defaultCastTimeOut);
1511        }
1512        catch (Exception JavaDoc e)
1513        {
1514          String JavaDoc msg = "An error occured while notifying all controllers of "
1515              + "failure to set savepoint " + name + " to transaction "
1516              + transactionId;
1517          logger.warn(msg, e);
1518          throw new SQLException JavaDoc(msg + " (" + e + ")");
1519        }
1520      }
1521
1522      if (success)
1523        return; // This is a success if at least one controller has succeeded
1524

1525      if (exception != null)
1526        throw exception;
1527
1528      // At this point, all controllers failed
1529

1530      if (controllersWithoutBackends != null)
1531      { // Notify all controllers without backend that have already logged the
1532
// request that they must remove it from the log
1533
int nbOfControllers = controllersWithoutBackends.size();
1534        for (int i = 0; i < nbOfControllers; i++)
1535        {
1536          Member member = (Member) controllersWithoutBackends.get(i);
1537          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1538              .getResult(member);
1539          try
1540          {
1541            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1542            dest.add(member);
1543            // Here we use the commit timeout field to transport the recovery
1544
// log id. This is ugly but convenient.
1545
dvdb.getMulticastRequestAdapter().multicastMessage(
1546                dest,
1547                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1548                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1549                MulticastRequestAdapter.WAIT_NONE,
1550                CJDBCGroupMessage.defaultCastTimeOut);
1551          }
1552          catch (Exception JavaDoc e)
1553          {
1554            String JavaDoc msg = "An error occured while notifying controllers "
1555                + member + " to unlog failed set savepoint " + name + " to "
1556                + "transaction " + transactionId;
1557            logger.error(msg, e);
1558          }
1559        }
1560      }
1561
1562      if (exception != null)
1563        throw exception;
1564      else
1565      {
1566        String JavaDoc msg = "Set savepoint " + name + " to transaction "
1567            + transactionId + " failed on all controllers";
1568        logger.warn(msg);
1569        throw new SQLException JavaDoc(msg);
1570      }
1571    }
1572    catch (SQLException JavaDoc e)
1573    {
1574      String JavaDoc msg = "Set savepoint " + name + " to transaction " + transactionId
1575          + " failed (" + e + ")";
1576      logger.warn(msg);
1577      throw e;
1578    }
1579  }
1580
1581  /**
1582   * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedReleaseSavepoint(long,
1583   * String)
1584   */

1585  public void distributedReleaseSavepoint(long transactionId, String JavaDoc name)
1586      throws SQLException JavaDoc
1587  {
1588    try
1589    {
1590      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1591      if (logger.isDebugEnabled())
1592        logger.debug("Broadcasting release savepoint " + name + " from "
1593            + "transaction " + transactionId + " to all controllers ("
1594            + dvdb.getChannel().getLocalMembership() + "->"
1595            + groupMembers.toString() + ")");
1596
1597      // Send the query to everybody including us
1598
MulticastResponse responses;
1599      try
1600      {
1601        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1602            groupMembers, new ReleaseSavepoint(transactionId, name),
1603            MulticastRequestAdapter.WAIT_ALL,
1604            CJDBCGroupMessage.defaultCastTimeOut);
1605      }
1606      catch (Exception JavaDoc e)
1607      {
1608        String JavaDoc msg = "An error occured while executing distributed release "
1609            + "savepoint " + name + " from transaction " + transactionId;
1610        logger.warn(msg, e);
1611        throw new SQLException JavaDoc(msg + "(" + e + ")");
1612      }
1613
1614      if (logger.isDebugEnabled())
1615        logger.debug("release savepoint " + name + " from transaction "
1616            + transactionId + " completed.");
1617
1618      if (responses.getFailedMembers() != null)
1619      { // Some controllers failed ... too bad !
1620
logger.warn(responses.getFailedMembers().size() + " controller(s) died"
1621            + " during execution of release savepoint " + name + " from "
1622            + "transaction " + transactionId);
1623      }
1624
1625      // List of controllers that gave a AllBackendsFailedException
1626
ArrayList JavaDoc failedOnAllBackends = null;
1627      // List of controllers that have no more backends to execute queries
1628
ArrayList JavaDoc controllersWithoutBackends = null;
1629      SQLException JavaDoc exception = null;
1630      int size = groupMembers.size();
1631      boolean success = false;
1632      // Get the result of each controller
1633
for (int i = 0; i < size; i++)
1634      {
1635        Member member = (Member) groupMembers.get(i);
1636        if ((responses.getFailedMembers() != null)
1637            && responses.getFailedMembers().contains(member))
1638        {
1639          logger.warn("Controller " + member + " is suspected of failure.");
1640          continue;
1641        }
1642        Object JavaDoc r = responses.getResult(member);
1643        if (r instanceof Boolean JavaDoc)
1644        {
1645          if (((Boolean JavaDoc) r).booleanValue())
1646            success = true;
1647          else
1648            logger.error("Unexpected result for controller " + member);
1649        }
1650        else if (r instanceof NoMoreBackendException)
1651        {
1652          if (controllersWithoutBackends == null)
1653            controllersWithoutBackends = new ArrayList JavaDoc();
1654          controllersWithoutBackends.add(member);
1655          if (logger.isDebugEnabled())
1656            logger.debug("Controller " + member + " has no more backends to "
1657                + "release savepoint " + name + " from transaction "
1658                + transactionId + " (" + r + ")");
1659        }
1660        else if (r instanceof AllBackendsFailedException)
1661        {
1662          if (failedOnAllBackends == null)
1663            failedOnAllBackends = new ArrayList JavaDoc();
1664          failedOnAllBackends.add(member);
1665          if (logger.isDebugEnabled())
1666            logger.debug("release savepoint failed on all backends of "
1667                + "controller " + member + " (" + r + ")");
1668        }
1669        else if (r instanceof SQLException JavaDoc)
1670        {
1671          String JavaDoc msg = "release savepoint " + name + " from transaction "
1672              + transactionId + " failed on controller " + member + " (" + r
1673              + ")";
1674          logger.warn(msg);
1675          exception = (SQLException JavaDoc) r;
1676        }
1677      }
1678
1679      if (failedOnAllBackends != null)
1680      { // Notify all controllers where all backend failed that the rollback
1681
// completed with 'success'
1682
AbstractRequest request = new UnknownRequest("release " + name, false,
1683            0, "\n");
1684        request.setTransactionId(transactionId);
1685        try
1686        {
1687          dvdb.getMulticastRequestAdapter().multicastMessage(
1688              failedOnAllBackends, new NotifyCompletion(request, success),
1689              MulticastRequestAdapter.WAIT_NONE,
1690              CJDBCGroupMessage.defaultCastTimeOut);
1691        }
1692        catch (Exception JavaDoc e)
1693        {
1694          String JavaDoc msg = "An error occured while notifying all controllers of "
1695              + "failure to release savepoint " + name + " from transaction "
1696              + transactionId;
1697          logger.warn(msg, e);
1698          throw new SQLException JavaDoc(msg + " (" + e + ")");
1699        }
1700      }
1701
1702      if (success)
1703        return; // This is a success if at least one controller has succeeded
1704

1705      if (exception != null)
1706        throw exception;
1707
1708      // At this point, all controllers failed
1709

1710      if (controllersWithoutBackends != null)
1711      { // Notify all controllers without backend that have already logged the
1712
// request that they must remove it from the log
1713
int nbOfControllers = controllersWithoutBackends.size();
1714        for (int i = 0; i < nbOfControllers; i++)
1715        {
1716          Member member = (Member) controllersWithoutBackends.get(i);
1717          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1718              .getResult(member);
1719          try
1720          {
1721            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1722            dest.add(member);
1723            // Here we use the commit timeout field to transport the recovery
1724
// log id. This is ugly but convenient.
1725
dvdb.getMulticastRequestAdapter().multicastMessage(
1726                dest,
1727                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1728                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1729                MulticastRequestAdapter.WAIT_NONE,
1730                CJDBCGroupMessage.defaultCastTimeOut);
1731          }
1732          catch (Exception JavaDoc e)
1733          {
1734            String JavaDoc msg = "An error occured while notifying controllers "
1735                + member + " to unlog failed release savepoint " + name
1736                + " from transaction " + transactionId;
1737            logger.error(msg, e);
1738          }
1739        }
1740      }
1741
1742      if (exception != null)
1743        throw exception;
1744      else
1745      {
1746        String JavaDoc msg = "Release savepoint " + name + " from transaction "
1747            + transactionId + " failed on all controllers";
1748        logger.warn(msg);
1749        throw new SQLException JavaDoc(msg);
1750      }
1751    }
1752    catch (SQLException JavaDoc e)
1753    {
1754      String JavaDoc msg = "Release savepoint " + name + " from transaction "
1755          + transactionId + " failed (" + e + ")";
1756      logger.warn(msg);
1757      throw e;
1758    }
1759  }
1760}
Popular Tags