KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 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 RAIDb2DistributedRequestManager
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 RAIDb2DistributedRequestManager extends DistributedRequestManager
76 {
77
78   /**
79    * Creates a new <code>RAIDb2DistributedRequestManager</code> instance
80    *
81    * @param vdb the virtual database this request manager belongs to
82    * @param scheduler the Request Scheduler to use
83    * @param cache a Query Cache implementation
84    * @param loadBalancer the Request Load Balancer to use
85    * @param recoveryLog the Log Recovery to use
86    * @param beginTimeout timeout in seconds for begin
87    * @param commitTimeout timeout in seconds for commit
88    * @param rollbackTimeout timeout in seconds for rollback
89    * @throws SQLException if an error occurs
90    * @throws NotCompliantMBeanException if the MBean is not JMX compliant
91    */

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

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

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

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

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

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

468   public ControllerResultSet execDistributedReadStoredProcedure(
469       StoredProcedure proc) throws SQLException JavaDoc
470   {
471     try
472     {
473       ControllerResultSet result = null;
474
475       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
476
477       if (logger.isDebugEnabled())
478         logger.debug("Broadcasting read stored procedure "
479             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
480             + (proc.isAutoCommit() ? "" : " transaction "
481                 + proc.getTransactionId()) + ") to all controllers ("
482             + dvdb.getChannel().getLocalMembership() + "->"
483             + groupMembers.toString() + ")");
484
485       // Send the query to everybody including us
486
// TODO: We could optimize the recipient list to the subset of controllers
487
// that have the needed tables.
488
MulticastResponse responses;
489       try
490       {
491         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
492             groupMembers, new ExecReadStoredProcedure(proc),
493             MulticastRequestAdapter.WAIT_ALL,
494             CJDBCGroupMessage.defaultCastTimeOut); // CHECK proc.getTimeout());
495
}
496       catch (Exception JavaDoc e)
497       {
498         String JavaDoc msg = "An error occured while executing distributed read stored procedure "
499             + proc.getId();
500         logger.warn(msg, e);
501         throw new SQLException JavaDoc(msg + " (" + e + ")");
502       }
503
504       if (logger.isDebugEnabled())
505         logger.debug("Stored procedure "
506             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
507             + " completed.");
508
509       if (responses.getFailedMembers() != null)
510       { // Some controllers failed ... too bad !
511
logger.warn(responses.getFailedMembers().size()
512             + " controller(s) died during execution of stored procedure "
513             + proc.getId());
514       }
515
516       // List of controllers that gave a AllBackendsFailedException
517
ArrayList JavaDoc failedOnAllBackends = null;
518       // List of controllers that have no more backends to execute queries
519
ArrayList JavaDoc controllersWithoutBackends = null;
520       SQLException JavaDoc exception = null;
521       int size = groupMembers.size();
522       // Get the result of each controller
523
for (int i = 0; i < size; i++)
524       {
525         Member member = (Member) groupMembers.get(i);
526         if ((responses.getFailedMembers() != null)
527             && responses.getFailedMembers().contains(member))
528         {
529           logger.warn("Controller " + member + " is suspected of failure.");
530           continue;
531         }
532         Object JavaDoc r = responses.getResult(member);
533         if (r instanceof ControllerResultSet)
534         {
535           if (result == null)
536             result = (ControllerResultSet) r;
537         }
538         else if (r instanceof AllBackendsFailedException)
539         {
540           if (failedOnAllBackends == null)
541             failedOnAllBackends = new ArrayList JavaDoc();
542           failedOnAllBackends.add(member);
543         }
544         else if (r instanceof NoMoreBackendException)
545         {
546           if (controllersWithoutBackends == null)
547             controllersWithoutBackends = new ArrayList JavaDoc();
548           controllersWithoutBackends.add(member);
549           if (logger.isDebugEnabled())
550             logger.debug("Controller " + member
551                 + " has no more backends to execute query (" + r + ")");
552         }
553         else if (r instanceof SQLException JavaDoc)
554         {
555           String JavaDoc msg = "Stored procedure " + proc.getId()
556               + " failed on controller " + member + " (" + r + ")";
557           logger.warn(msg);
558           exception = (SQLException JavaDoc) r;
559         }
560       }
561
562       if (failedOnAllBackends != null)
563       { // Notify all controllers of completion
564
try
565         {
566           dvdb.getMulticastRequestAdapter().multicastMessage(
567               failedOnAllBackends, new NotifyCompletion(proc, result != null),
568               MulticastRequestAdapter.WAIT_NONE,
569               CJDBCGroupMessage.defaultCastTimeOut); // CHECK
570
// proc.getTimeout());
571
}
572         catch (Exception JavaDoc e)
573         {
574           String JavaDoc msg = "An error occured while notifying all controllers of failure of read stored procedure "
575               + proc.getId();
576           logger.warn(msg, e);
577           throw new SQLException JavaDoc(msg + " (" + e + ")");
578         }
579       }
580
581       if (result != null)
582       {
583         if (logger.isDebugEnabled())
584           logger.debug("Stored procedure " + proc.getId()
585               + " completed successfully.");
586         return result; // Success
587
}
588
589       // At this point, all controllers failed
590

591       if (controllersWithoutBackends != null)
592       { // Notify all controllers without backend that have already logged the
593
// request that they must remove it from the log
594

595         int nbOfControllers = controllersWithoutBackends.size();
596         for (int i = 0; i < nbOfControllers; i++)
597         {
598           Member member = (Member) controllersWithoutBackends.get(i);
599           NoMoreBackendException nmbe = (NoMoreBackendException) responses
600               .getResult(member);
601           try
602           {
603             ArrayList JavaDoc dest = new ArrayList JavaDoc();
604             dest.add(member);
605             dvdb.getMulticastRequestAdapter().multicastMessage(dest,
606                 new UnlogRequest(proc, nmbe.getRecoveryLogId()),
607                 MulticastRequestAdapter.WAIT_NONE,
608                 CJDBCGroupMessage.defaultCastTimeOut); // CHECK
609
// proc.getTimeout());
610
}
611           catch (Exception JavaDoc e)
612           {
613             String JavaDoc msg = "An error occured while notifying controllers "
614                 + member
615                 + " to unlog failed distributed read stored procedure "
616                 + proc.getId();
617             logger.error(msg, e);
618           }
619         }
620       }
621
622       if (exception != null)
623         throw exception;
624       else
625       {
626         String JavaDoc msg = "Stored procedure '" + proc
627             + "' failed on all controllers";
628         logger.warn(msg);
629         throw new SQLException JavaDoc(msg);
630       }
631     }
632     catch (SQLException JavaDoc e)
633     {
634       String JavaDoc msg = Translate.get("loadbalancer.request.failed", new String JavaDoc[]{
635           proc.getSQLShortForm(vdb.getSQLShortFormLength()), e.getMessage()});
636       logger.warn(msg);
637       throw e;
638     }
639   }
640
641   /**
642    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#execDistributedWriteStoredProcedure(org.objectweb.cjdbc.common.sql.StoredProcedure)
643    */

644   public int execDistributedWriteStoredProcedure(StoredProcedure proc)
645       throws SQLException JavaDoc
646   {
647     try
648     {
649       int execWriteStoredProcedureResult = -1;
650
651       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
652
653       if (logger.isDebugEnabled())
654         logger.debug("Broadcasting stored procedure "
655             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
656             + (proc.isAutoCommit() ? "" : " transaction "
657                 + proc.getTransactionId()) + ") to all controllers ("
658             + dvdb.getChannel().getLocalMembership() + "->"
659             + groupMembers.toString() + ")");
660
661       // Send the query to everybody including us
662
// TODO: We could optimize the recipient list to the subset of controllers
663
// that have the needed tables.
664
MulticastResponse responses;
665       try
666       {
667         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
668             groupMembers, new ExecWriteStoredProcedure(proc),
669             MulticastRequestAdapter.WAIT_ALL,
670             CJDBCGroupMessage.defaultCastTimeOut); // CHECK proc.getTimeout());
671
}
672       catch (Exception JavaDoc e)
673       {
674         String JavaDoc msg = "An error occured while executing distributed write stored procedure "
675             + proc.getId();
676         logger.warn(msg, e);
677         throw new SQLException JavaDoc(msg + " (" + e + ")");
678       }
679
680       if (logger.isDebugEnabled())
681         logger.debug("Stored procedure "
682             + proc.getSQLShortForm(dvdb.getSQLShortFormLength())
683             + " completed.");
684
685       if (responses.getFailedMembers() != null)
686       { // Some controllers failed ... too bad !
687
logger.warn(responses.getFailedMembers().size()
688             + " controller(s) died during execution of stored procedure "
689             + proc.getId());
690       }
691
692       // List of controllers that gave a AllBackendsFailedException
693
ArrayList JavaDoc failedOnAllBackends = null;
694       // List of controllers that have no more backends to execute queries
695
ArrayList JavaDoc controllersWithoutBackends = null;
696       SQLException JavaDoc exception = null;
697       int size = groupMembers.size();
698       // Get the result of each controller
699
for (int i = 0; i < size; i++)
700       {
701         Member member = (Member) groupMembers.get(i);
702         if ((responses.getFailedMembers() != null)
703             && responses.getFailedMembers().contains(member))
704         {
705           logger.warn("Controller " + member + " is suspected of failure.");
706           continue;
707         }
708         Object JavaDoc r = responses.getResult(member);
709         if (r instanceof Integer JavaDoc)
710         {
711           if (execWriteStoredProcedureResult != -1)
712             execWriteStoredProcedureResult = ((Integer JavaDoc) r).intValue();
713         }
714         else if (r instanceof AllBackendsFailedException)
715         {
716           if (failedOnAllBackends == null)
717             failedOnAllBackends = new ArrayList JavaDoc();
718           failedOnAllBackends.add(member);
719         }
720         else if (r instanceof NoMoreBackendException)
721         {
722           if (controllersWithoutBackends == null)
723             controllersWithoutBackends = new ArrayList JavaDoc();
724           controllersWithoutBackends.add(member);
725           if (logger.isDebugEnabled())
726             logger.debug("Controller " + member
727                 + " has no more backends to execute query (" + r + ")");
728         }
729         else if (r instanceof SQLException JavaDoc)
730         {
731           String JavaDoc msg = "Stored procedure " + proc.getId()
732               + " failed on controller " + member + " (" + r + ")";
733           logger.warn(msg);
734           exception = (SQLException JavaDoc) r;
735         }
736       }
737
738       if (failedOnAllBackends != null)
739       { // Notify all controllers of completion
740
try
741         {
742           dvdb.getMulticastRequestAdapter().multicastMessage(
743               failedOnAllBackends,
744               new NotifyCompletion(proc, execWriteStoredProcedureResult != -1),
745               MulticastRequestAdapter.WAIT_NONE,
746               CJDBCGroupMessage.defaultCastTimeOut); // CHECK
747
// proc.getTimeout());
748
}
749         catch (Exception JavaDoc e)
750         {
751           String JavaDoc msg = "An error occured while notifying all controllers of failure of write stored procedure "
752               + proc.getId();
753           logger.warn(msg, e);
754           throw new SQLException JavaDoc(msg + " (" + e + ")");
755         }
756       }
757
758       if (execWriteStoredProcedureResult != NO_RESULT)
759       {
760         if (logger.isDebugEnabled())
761           logger.debug("Stored procedure " + proc.getId()
762               + " completed successfully.");
763         return execWriteStoredProcedureResult; // Success
764
}
765
766       // At this point, all controllers failed
767

768       if (controllersWithoutBackends != null)
769       { // Notify all controllers without backend that have already logged the
770
// request that they must remove it from the log
771

772         int nbOfControllers = controllersWithoutBackends.size();
773         for (int i = 0; i < nbOfControllers; i++)
774         {
775           Member member = (Member) controllersWithoutBackends.get(i);
776           NoMoreBackendException nmbe = (NoMoreBackendException) responses
777               .getResult(member);
778           try
779           {
780             ArrayList JavaDoc dest = new ArrayList JavaDoc();
781             dest.add(member);
782             dvdb.getMulticastRequestAdapter().multicastMessage(dest,
783                 new UnlogRequest(proc, nmbe.getRecoveryLogId()),
784                 MulticastRequestAdapter.WAIT_NONE,
785                 CJDBCGroupMessage.defaultCastTimeOut); // CHECK
786
// proc.getTimeout());
787
}
788           catch (Exception JavaDoc e)
789           {
790             String JavaDoc msg = "An error occured while notifying controllers "
791                 + member
792                 + " to unlog failed distributed write stored procedure "
793                 + proc.getId();
794             logger.error(msg, e);
795           }
796         }
797       }
798
799       if (exception != null)
800         throw exception;
801       else
802       {
803         String JavaDoc msg = "Stored procedure '" + proc
804             + "' failed on all controllers";
805         logger.warn(msg);
806         throw new SQLException JavaDoc(msg);
807       }
808     }
809     catch (SQLException JavaDoc e)
810     {
811       String JavaDoc msg = Translate.get("loadbalancer.request.failed", new String JavaDoc[]{
812           proc.getSQLShortForm(vdb.getSQLShortFormLength()), e.getMessage()});
813       logger.warn(msg);
814       throw e;
815     }
816   }
817
818   /**
819    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedCommit(String,
820    * long)
821    */

822   public void distributedCommit(String JavaDoc login, long transactionId)
823       throws SQLException JavaDoc
824   {
825     try
826     {
827       ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
828       if (logger.isDebugEnabled())
829         logger.debug("Broadcasting transaction " + transactionId
830             + " commit to all controllers ("
831             + dvdb.getChannel().getLocalMembership() + "->"
832             + groupMembers.toString() + ")");
833
834       // Send the query to everybody including us
835
MulticastResponse responses;
836       try
837       {
838         responses = dvdb.getMulticastRequestAdapter().multicastMessage(
839             groupMembers, new Commit(login, transactionId),
840             MulticastRequestAdapter.WAIT_ALL,
841             CJDBCGroupMessage.defaultCastTimeOut); // CHECK
842
// this.commitTimeout);
843
}
844       catch (Exception JavaDoc e)
845       {
846         String JavaDoc msg = "An error occured while executing distributed rollback for transaction "
847             + transactionId;
848         logger.warn(msg, e);
849         throw new SQLException JavaDoc(msg + "(" + e + ")");
850       }
851
852       if (logger.isDebugEnabled())
853         logger.debug("Commit of transaction " + transactionId + " completed.");
854
855       if (responses.getFailedMembers() != null)
856       { // Some controllers failed ... too bad !
857
logger.warn(responses.getFailedMembers().size()
858             + " controller(s) died during execution of commit for transaction "
859             + transactionId);
860       }
861
862       // List of controllers that gave a AllBackendsFailedException
863
ArrayList JavaDoc failedOnAllBackends = null;
864       // List of controllers that have no more backends to execute queries
865
ArrayList JavaDoc controllersWithoutBackends = null;
866       SQLException JavaDoc exception = null;
867       int size = groupMembers.size();
868       boolean success = false;
869       // Get the result of each controller
870
for (int i = 0; i < size; i++)
871       {
872         Member member = (Member) groupMembers.get(i);
873         if ((responses.getFailedMembers() != null)
874             && responses.getFailedMembers().contains(member))
875         {
876           logger.warn("Controller " + member + " is suspected of failure.");
877           continue;
878         }
879         Object JavaDoc r = responses.getResult(member);
880         if (r instanceof Boolean JavaDoc)
881         {
882           if (((Boolean JavaDoc) r).booleanValue())
883             success = true;
884           else
885             logger.error("Unexpected result for controller " + member);
886         }
887         else if (r instanceof AllBackendsFailedException)
888         {
889           if (failedOnAllBackends == null)
890             failedOnAllBackends = new ArrayList JavaDoc();
891           failedOnAllBackends.add(member);
892           if (logger.isDebugEnabled())
893             logger.debug("Commit failed on all backends of controller "
894                 + member + " (" + r + ")");
895         }
896         else if (r instanceof NoMoreBackendException)
897         {
898           if (controllersWithoutBackends == null)
899             controllersWithoutBackends = new ArrayList JavaDoc();
900           controllersWithoutBackends.add(member);
901           if (logger.isDebugEnabled())
902             logger.debug("Controller " + member
903                 + " has no more backends to commit transaction "
904                 + transactionId + " (" + r + ")");
905         }
906         else if (r instanceof SQLException JavaDoc)
907         {
908           String JavaDoc msg = "Commit of transaction " + transactionId
909               + " failed on controller " + member + " (" + r + ")";
910           logger.warn(msg);
911           exception = (SQLException JavaDoc) r;
912         }
913       }
914
915       if (failedOnAllBackends != null)
916       { // Notify all controllers where all backend failed that the commit
917
// completed with 'success'
918
AbstractRequest request = new UnknownRequest("commit", false, 0, "\n");
919         request.setTransactionId(transactionId);
920         try
921         {
922           dvdb.getMulticastRequestAdapter().multicastMessage(
923               failedOnAllBackends, new NotifyCompletion(request, success),
924               MulticastRequestAdapter.WAIT_NONE,
925               CJDBCGroupMessage.defaultCastTimeOut); // CHECK commitTimeout);
926
}
927         catch (Exception JavaDoc e)
928         {
929           String JavaDoc msg = "An error occured while notifying all controllers of failure to commit transaction "
930               + transactionId;
931           logger.warn(msg, e);
932           throw new SQLException JavaDoc(msg + " (" + e + ")");
933         }
934       }
935
936       if (success)
937         return; // This is a success if at least one controller has succeeded
938

939       // At this point, all controllers failed
940

941       if (controllersWithoutBackends != null)
942       { // Notify all controllers without backend that have already logged the
943
// request that they must remove it from the log
944

945         int nbOfControllers = controllersWithoutBackends.size();
946         for (int i = 0; i < nbOfControllers; i++)
947         {
948           Member member = (Member) controllersWithoutBackends.get(i);
949           NoMoreBackendException nmbe = (NoMoreBackendException) responses
950               .getResult(member);
951           try
952           {
953             ArrayList JavaDoc dest = new ArrayList JavaDoc();
954             dest.add(member);
955             // Here we use the commit timeout field to transport the recovery
956
// log id. This is ugly but convenient.
957
dvdb.getMulticastRequestAdapter().multicastMessage(
958                 dest,
959                 new UnlogCommit(new TransactionMarkerMetaData(transactionId,
960                     nmbe.getRecoveryLogId(), nmbe.getLogin())),
961                 MulticastRequestAdapter.WAIT_NONE,
962                 CJDBCGroupMessage.defaultCastTimeOut); // CHECK
963
// this.commitTimeout);
964
}
965           catch (Exception JavaDoc e)
966           {
967             String JavaDoc msg = "An error occured while notifying controllers "
968                 + member + " to unlog failed commit for transaction "
969                 + transactionId;
970             logger.error(msg, e);
971           }
972         }
973       }
974
975       if (exception != null)
976         throw exception;
977       else
978       {
979         String JavaDoc msg = "Transaction " + transactionId
980             + " failed to commit on all controllers";
981         logger.warn(msg);
982         throw new SQLException JavaDoc(msg);
983       }
984     }
985     catch (SQLException JavaDoc e)
986     {
987       String JavaDoc msg = "Transaction " + transactionId + " commit failed (" + e
988           + ")";
989       logger.warn(msg);
990       throw e;
991     }
992   }
993
994   /**
995    * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedRollback(String,
996    * long)
997    */

998   public void distributedRollback(String JavaDoc login, long transactionId)
999       throws SQLException JavaDoc
1000  {
1001    try
1002    {
1003      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1004      if (logger.isDebugEnabled())
1005        logger.debug("Broadcasting transaction " + transactionId
1006            + " rollback to all controllers ("
1007            + dvdb.getChannel().getLocalMembership() + "->"
1008            + groupMembers.toString() + ")");
1009
1010      // Send the query to everybody including us
1011
MulticastResponse responses;
1012      try
1013      {
1014        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1015            groupMembers, new Rollback(login, transactionId),
1016            MulticastRequestAdapter.WAIT_ALL,
1017            CJDBCGroupMessage.defaultCastTimeOut); // CHECK
1018
// this.rollbackTimeout);
1019
}
1020      catch (Exception JavaDoc e)
1021      {
1022        String JavaDoc msg = "An error occured while executing distributed rollback for transaction "
1023            + transactionId;
1024        logger.warn(msg, e);
1025        throw new SQLException JavaDoc(msg + "(" + e + ")");
1026      }
1027
1028      if (logger.isDebugEnabled())
1029        logger
1030            .debug("rollback of transaction " + transactionId + " completed.");
1031
1032      if (responses.getFailedMembers() != null)
1033      { // Some controllers failed ... too bad !
1034
logger
1035            .warn(responses.getFailedMembers().size()
1036                + " controller(s) died during execution of rollback for transaction "
1037                + transactionId);
1038      }
1039
1040      // List of controllers that gave a AllBackendsFailedException
1041
ArrayList JavaDoc failedOnAllBackends = null;
1042      // List of controllers that have no more backends to execute queries
1043
ArrayList JavaDoc controllersWithoutBackends = null;
1044      SQLException JavaDoc exception = null;
1045      int size = groupMembers.size();
1046      boolean success = false;
1047      // Get the result of each controller
1048
for (int i = 0; i < size; i++)
1049      {
1050        Member member = (Member) groupMembers.get(i);
1051        if ((responses.getFailedMembers() != null)
1052            && responses.getFailedMembers().contains(member))
1053        {
1054          logger.warn("Controller " + member + " is suspected of failure.");
1055          continue;
1056        }
1057        Object JavaDoc r = responses.getResult(member);
1058        if (r instanceof Boolean JavaDoc)
1059        {
1060          if (((Boolean JavaDoc) r).booleanValue())
1061            success = true;
1062          else
1063            logger.error("Unexpected result for controller " + member);
1064        }
1065        else if (r instanceof AllBackendsFailedException)
1066        {
1067          if (failedOnAllBackends == null)
1068            failedOnAllBackends = new ArrayList JavaDoc();
1069          failedOnAllBackends.add(member);
1070          if (logger.isDebugEnabled())
1071            logger.debug("rollback failed on all backends of controller "
1072                + member + " (" + r + ")");
1073        }
1074        else if (r instanceof NoMoreBackendException)
1075        {
1076          if (controllersWithoutBackends == null)
1077            controllersWithoutBackends = new ArrayList JavaDoc();
1078          controllersWithoutBackends.add(member);
1079          if (logger.isDebugEnabled())
1080            logger.debug("Controller " + member
1081                + " has no more backends to rollback transaction "
1082                + transactionId + " (" + r + ")");
1083        }
1084        else if (r instanceof SQLException JavaDoc)
1085        {
1086          String JavaDoc msg = "rollback of transaction " + transactionId
1087              + " failed on controller " + member + " (" + r + ")";
1088          logger.warn(msg);
1089          exception = (SQLException JavaDoc) r;
1090        }
1091      }
1092
1093      if (failedOnAllBackends != null)
1094      { // Notify all controllers where all backend failed that the rollback
1095
// completed with 'success'
1096
AbstractRequest request = new UnknownRequest("rollback", false, 0, "\n");
1097        request.setTransactionId(transactionId);
1098        try
1099        {
1100          dvdb.getMulticastRequestAdapter().multicastMessage(
1101              failedOnAllBackends, new NotifyCompletion(request, success),
1102              MulticastRequestAdapter.WAIT_NONE,
1103              CJDBCGroupMessage.defaultCastTimeOut); // CHECK rollbackTimeout);
1104
}
1105        catch (Exception JavaDoc e)
1106        {
1107          String JavaDoc msg = "An error occured while notifying all controllers of failure to rollback transaction "
1108              + transactionId;
1109          logger.warn(msg, e);
1110          throw new SQLException JavaDoc(msg + " (" + e + ")");
1111        }
1112      }
1113
1114      if (success)
1115        return; // This is a success if at least one controller has succeeded
1116

1117      if (exception != null)
1118        throw exception;
1119
1120      // At this point, all controllers failed
1121

1122      if (controllersWithoutBackends != null)
1123      { // Notify all controllers without backend that have already logged the
1124
// request that they must remove it from the log
1125

1126        int nbOfControllers = controllersWithoutBackends.size();
1127        for (int i = 0; i < nbOfControllers; i++)
1128        {
1129          Member member = (Member) controllersWithoutBackends.get(i);
1130          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1131              .getResult(member);
1132          try
1133          {
1134            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1135            dest.add(member);
1136            // Here we use the commit timeout field to transport the recovery
1137
// log id. This is ugly but convenient.
1138
dvdb.getMulticastRequestAdapter().multicastMessage(
1139                dest,
1140                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1141                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1142                MulticastRequestAdapter.WAIT_NONE,
1143                CJDBCGroupMessage.defaultCastTimeOut); // CHECK
1144
// this.commitTimeout);
1145
}
1146          catch (Exception JavaDoc e)
1147          {
1148            String JavaDoc msg = "An error occured while notifying controllers "
1149                + member + " to unlog failed rollback for transaction "
1150                + transactionId;
1151            logger.error(msg, e);
1152          }
1153        }
1154      }
1155
1156      if (exception != null)
1157        throw exception;
1158      else
1159      {
1160        String JavaDoc msg = "Transaction " + transactionId
1161            + " failed to rollback on all controllers";
1162        logger.warn(msg);
1163        throw new SQLException JavaDoc(msg);
1164      }
1165    }
1166    catch (SQLException JavaDoc e)
1167    {
1168      String JavaDoc msg = "Transaction " + transactionId + " rollback failed (" + e
1169          + ")";
1170      logger.warn(msg);
1171      throw e;
1172    }
1173  }
1174
1175  /**
1176   * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedRollback(long,
1177   * String)
1178   */

1179  public void distributedRollback(long transactionId, String JavaDoc savepointName)
1180      throws SQLException JavaDoc
1181  {
1182    try
1183    {
1184      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1185      if (logger.isDebugEnabled())
1186        logger.debug("Broadcasting rollback to savepoint " + savepointName
1187            + " for transaction " + transactionId + " to all controllers ("
1188            + dvdb.getChannel().getLocalMembership() + "->"
1189            + groupMembers.toString() + ")");
1190
1191      // Send the query to everybody including us
1192
MulticastResponse responses;
1193      try
1194      {
1195        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1196            groupMembers,
1197            new RollbackToSavepoint(transactionId, savepointName),
1198            MulticastRequestAdapter.WAIT_ALL,
1199            CJDBCGroupMessage.defaultCastTimeOut);
1200      }
1201      catch (Exception JavaDoc e)
1202      {
1203        String JavaDoc msg = "An error occured while executing distributed rollback to"
1204            + " savepoint " + savepointName + " for transaction "
1205            + transactionId;
1206        logger.warn(msg, e);
1207        throw new SQLException JavaDoc(msg + "(" + e + ")");
1208      }
1209
1210      if (logger.isDebugEnabled())
1211        logger.debug("rollback to savepoint " + savepointName + " for "
1212            + "transaction " + transactionId + " completed.");
1213
1214      if (responses.getFailedMembers() != null)
1215      { // Some controllers failed ... too bad !
1216
logger.warn(responses.getFailedMembers().size() + " controller(s) died"
1217            + " during execution of rollback to savepoint " + savepointName
1218            + " for transaction " + transactionId);
1219      }
1220
1221      // List of controllers that gave a AllBackendsFailedException
1222
ArrayList JavaDoc failedOnAllBackends = null;
1223      // List of controllers that have no more backends to execute queries
1224
ArrayList JavaDoc controllersWithoutBackends = null;
1225      SQLException JavaDoc exception = null;
1226      int size = groupMembers.size();
1227      boolean success = false;
1228      // Get the result of each controller
1229
for (int i = 0; i < size; i++)
1230      {
1231        Member member = (Member) groupMembers.get(i);
1232        if ((responses.getFailedMembers() != null)
1233            && responses.getFailedMembers().contains(member))
1234        {
1235          logger.warn("Controller " + member + " is suspected of failure.");
1236          continue;
1237        }
1238        Object JavaDoc r = responses.getResult(member);
1239        if (r instanceof Boolean JavaDoc)
1240        {
1241          if (((Boolean JavaDoc) r).booleanValue())
1242            success = true;
1243          else
1244            logger.error("Unexpected result for controller " + member);
1245        }
1246        else if (r instanceof AllBackendsFailedException)
1247        {
1248          if (failedOnAllBackends == null)
1249            failedOnAllBackends = new ArrayList JavaDoc();
1250          failedOnAllBackends.add(member);
1251          if (logger.isDebugEnabled())
1252            logger.debug("rollback to savepoint failed on all backends of "
1253                + "controller " + member + " (" + r + ")");
1254        }
1255        else if (r instanceof NoMoreBackendException)
1256        {
1257          if (controllersWithoutBackends == null)
1258            controllersWithoutBackends = new ArrayList JavaDoc();
1259          controllersWithoutBackends.add(member);
1260          if (logger.isDebugEnabled())
1261            logger.debug("Controller " + member + " has no more backends to "
1262                + "rollback to savepoint " + savepointName + " for "
1263                + "transaction " + transactionId + " (" + r + ")");
1264        }
1265        else if (r instanceof SQLException JavaDoc)
1266        {
1267          String JavaDoc msg = "rollback to savepoint " + savepointName + " for "
1268              + "transaction " + transactionId + " failed on controller "
1269              + member + " (" + r + ")";
1270          logger.warn(msg);
1271          exception = (SQLException JavaDoc) r;
1272        }
1273      }
1274
1275      if (failedOnAllBackends != null)
1276      { // Notify all controllers where all backend failed that the rollback
1277
// completed with 'success'
1278
AbstractRequest request = new UnknownRequest("rollback "
1279            + savepointName, false, 0, "\n");
1280        request.setTransactionId(transactionId);
1281        try
1282        {
1283          dvdb.getMulticastRequestAdapter().multicastMessage(
1284              failedOnAllBackends, new NotifyCompletion(request, success),
1285              MulticastRequestAdapter.WAIT_NONE,
1286              CJDBCGroupMessage.defaultCastTimeOut);
1287        }
1288        catch (Exception JavaDoc e)
1289        {
1290          String JavaDoc msg = "An error occured while notifying all controllers of "
1291              + "failure to rollback to savepoint " + savepointName + " for "
1292              + "transaction " + transactionId;
1293          logger.warn(msg, e);
1294          throw new SQLException JavaDoc(msg + " (" + e + ")");
1295        }
1296      }
1297
1298      if (success)
1299        return; // This is a success if at least one controller has succeeded
1300

1301      if (exception != null)
1302        throw exception;
1303
1304      // At this point, all controllers failed
1305

1306      if (controllersWithoutBackends != null)
1307      { // Notify all controllers without backend that have already logged the
1308
// request that they must remove it from the log
1309
int nbOfControllers = controllersWithoutBackends.size();
1310        for (int i = 0; i < nbOfControllers; i++)
1311        {
1312          Member member = (Member) controllersWithoutBackends.get(i);
1313          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1314              .getResult(member);
1315          try
1316          {
1317            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1318            dest.add(member);
1319            // Here we use the commit timeout field to transport the recovery
1320
// log id. This is ugly but convenient.
1321
dvdb.getMulticastRequestAdapter().multicastMessage(
1322                dest,
1323                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1324                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1325                MulticastRequestAdapter.WAIT_NONE,
1326                CJDBCGroupMessage.defaultCastTimeOut);
1327          }
1328          catch (Exception JavaDoc e)
1329          {
1330            String JavaDoc msg = "An error occured while notifying controllers "
1331                + member + " to unlog failed rollback to savepoint "
1332                + savepointName + " for transaction " + transactionId;
1333            logger.error(msg, e);
1334          }
1335        }
1336      }
1337
1338      if (exception != null)
1339        throw exception;
1340      else
1341      {
1342        String JavaDoc msg = "Rollback to savepoint " + savepointName + " for "
1343            + "transaction " + transactionId + " failed on all controllers";
1344        logger.warn(msg);
1345        throw new SQLException JavaDoc(msg);
1346      }
1347    }
1348    catch (SQLException JavaDoc e)
1349    {
1350      String JavaDoc msg = "Rollback to savepoint " + savepointName + " for "
1351          + "transaction " + transactionId + " failed (" + e + ")";
1352      logger.warn(msg);
1353      throw e;
1354    }
1355  }
1356
1357  /**
1358   * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedSetSavepoint(long,
1359   * String)
1360   */

1361  public void distributedSetSavepoint(long transactionId, String JavaDoc name)
1362      throws SQLException JavaDoc
1363  {
1364    try
1365    {
1366      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1367      if (logger.isDebugEnabled())
1368        logger.debug("Broadcasting set savepoint " + name + " to transaction "
1369            + transactionId + " to all controllers ("
1370            + dvdb.getChannel().getLocalMembership() + "->"
1371            + groupMembers.toString() + ")");
1372
1373      // Send the query to everybody including us
1374
MulticastResponse responses;
1375      try
1376      {
1377        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1378            groupMembers, new SetSavepoint(transactionId, name),
1379            MulticastRequestAdapter.WAIT_ALL,
1380            CJDBCGroupMessage.defaultCastTimeOut);
1381      }
1382      catch (Exception JavaDoc e)
1383      {
1384        String JavaDoc msg = "An error occured while executing distributed set "
1385            + "savepoint " + name + " to transaction " + transactionId;
1386        logger.warn(msg, e);
1387        throw new SQLException JavaDoc(msg + "(" + e + ")");
1388      }
1389
1390      if (logger.isDebugEnabled())
1391        logger.debug("set savepoint " + name + " to transaction "
1392            + transactionId + " completed.");
1393
1394      if (responses.getFailedMembers() != null)
1395      { // Some controllers failed ... too bad !
1396
logger.warn(responses.getFailedMembers().size() + " controller(s) died"
1397            + " during execution of set savepoint " + name + " to transaction "
1398            + transactionId);
1399      }
1400
1401      // List of controllers that gave a AllBackendsFailedException
1402
ArrayList JavaDoc failedOnAllBackends = null;
1403      // List of controllers that have no more backends to execute queries
1404
ArrayList JavaDoc controllersWithoutBackends = null;
1405      SQLException JavaDoc exception = null;
1406      int size = groupMembers.size();
1407      boolean success = false;
1408      // Get the result of each controller
1409
for (int i = 0; i < size; i++)
1410      {
1411        Member member = (Member) groupMembers.get(i);
1412        if ((responses.getFailedMembers() != null)
1413            && responses.getFailedMembers().contains(member))
1414        {
1415          logger.warn("Controller " + member + " is suspected of failure.");
1416          continue;
1417        }
1418        Object JavaDoc r = responses.getResult(member);
1419        if (r instanceof Boolean JavaDoc)
1420        {
1421          if (((Boolean JavaDoc) r).booleanValue())
1422            success = true;
1423          else
1424            logger.error("Unexpected result for controller " + member);
1425        }
1426        else if (r instanceof AllBackendsFailedException)
1427        {
1428          if (failedOnAllBackends == null)
1429            failedOnAllBackends = new ArrayList JavaDoc();
1430          failedOnAllBackends.add(member);
1431          if (logger.isDebugEnabled())
1432            logger.debug("set savepoint failed on all backends of controller "
1433                + member + " (" + r + ")");
1434        }
1435        else if (r instanceof NoMoreBackendException)
1436        {
1437          if (controllersWithoutBackends == null)
1438            controllersWithoutBackends = new ArrayList JavaDoc();
1439          controllersWithoutBackends.add(member);
1440          if (logger.isDebugEnabled())
1441            logger.debug("Controller " + member + " has no more backends to "
1442                + "set savepoint " + name + " to transaction " + transactionId
1443                + " (" + r + ")");
1444        }
1445        else if (r instanceof SQLException JavaDoc)
1446        {
1447          String JavaDoc msg = "set savepoint " + name + " to transaction "
1448              + transactionId + " failed on controller " + member + " (" + r
1449              + ")";
1450          logger.warn(msg);
1451          exception = (SQLException JavaDoc) r;
1452        }
1453      }
1454
1455      if (failedOnAllBackends != null)
1456      { // Notify all controllers where all backend failed that the rollback
1457
// completed with 'success'
1458
AbstractRequest request = new UnknownRequest("savepoint " + name,
1459            false, 0, "\n");
1460        request.setTransactionId(transactionId);
1461        try
1462        {
1463          dvdb.getMulticastRequestAdapter().multicastMessage(
1464              failedOnAllBackends, new NotifyCompletion(request, success),
1465              MulticastRequestAdapter.WAIT_NONE,
1466              CJDBCGroupMessage.defaultCastTimeOut);
1467        }
1468        catch (Exception JavaDoc e)
1469        {
1470          String JavaDoc msg = "An error occured while notifying all controllers of "
1471              + "failure to set savepoint " + name + " to transaction "
1472              + transactionId;
1473          logger.warn(msg, e);
1474          throw new SQLException JavaDoc(msg + " (" + e + ")");
1475        }
1476      }
1477
1478      if (success)
1479        return; // This is a success if at least one controller has succeeded
1480

1481      if (exception != null)
1482        throw exception;
1483
1484      // At this point, all controllers failed
1485

1486      if (controllersWithoutBackends != null)
1487      { // Notify all controllers without backend that have already logged the
1488
// request that they must remove it from the log
1489
int nbOfControllers = controllersWithoutBackends.size();
1490        for (int i = 0; i < nbOfControllers; i++)
1491        {
1492          Member member = (Member) controllersWithoutBackends.get(i);
1493          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1494              .getResult(member);
1495          try
1496          {
1497            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1498            dest.add(member);
1499            // Here we use the commit timeout field to transport the recovery
1500
// log id. This is ugly but convenient.
1501
dvdb.getMulticastRequestAdapter().multicastMessage(
1502                dest,
1503                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1504                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1505                MulticastRequestAdapter.WAIT_NONE,
1506                CJDBCGroupMessage.defaultCastTimeOut);
1507          }
1508          catch (Exception JavaDoc e)
1509          {
1510            String JavaDoc msg = "An error occured while notifying controllers "
1511                + member + " to unlog failed set savepoint " + name + " to "
1512                + "transaction " + transactionId;
1513            logger.error(msg, e);
1514          }
1515        }
1516      }
1517
1518      if (exception != null)
1519        throw exception;
1520      else
1521      {
1522        String JavaDoc msg = "Set savepoint " + name + " to transaction "
1523            + transactionId + " failed on all controllers";
1524        logger.warn(msg);
1525        throw new SQLException JavaDoc(msg);
1526      }
1527    }
1528    catch (SQLException JavaDoc e)
1529    {
1530      String JavaDoc msg = "Set savepoint " + name + " to transaction " + transactionId
1531          + " failed (" + e + ")";
1532      logger.warn(msg);
1533      throw e;
1534    }
1535  }
1536
1537  /**
1538   * @see org.objectweb.cjdbc.controller.requestmanager.distributed.DistributedRequestManager#distributedReleaseSavepoint(long,
1539   * String)
1540   */

1541  public void distributedReleaseSavepoint(long transactionId, String JavaDoc name)
1542      throws SQLException JavaDoc
1543  {
1544    try
1545    {
1546      ArrayList JavaDoc groupMembers = dvdb.getCurrentGroup().getMembers();
1547      if (logger.isDebugEnabled())
1548        logger.debug("Broadcasting release savepoint " + name + " from "
1549            + "transaction " + transactionId + " to all controllers ("
1550            + dvdb.getChannel().getLocalMembership() + "->"
1551            + groupMembers.toString() + ")");
1552
1553      // Send the query to everybody including us
1554
MulticastResponse responses;
1555      try
1556      {
1557        responses = dvdb.getMulticastRequestAdapter().multicastMessage(
1558            groupMembers, new ReleaseSavepoint(transactionId, name),
1559            MulticastRequestAdapter.WAIT_ALL,
1560            CJDBCGroupMessage.defaultCastTimeOut);
1561      }
1562      catch (Exception JavaDoc e)
1563      {
1564        String JavaDoc msg = "An error occured while executing distributed release "
1565            + "savepoint " + name + " from transaction " + transactionId;
1566        logger.warn(msg, e);
1567        throw new SQLException JavaDoc(msg + "(" + e + ")");
1568      }
1569
1570      if (logger.isDebugEnabled())
1571        logger.debug("release savepoint " + name + " from transaction "
1572            + transactionId + " completed.");
1573
1574      if (responses.getFailedMembers() != null)
1575      { // Some controllers failed ... too bad !
1576
logger.warn(responses.getFailedMembers().size() + " controller(s) died"
1577            + " during execution of release savepoint " + name + " from "
1578            + "transaction " + transactionId);
1579      }
1580
1581      // List of controllers that gave a AllBackendsFailedException
1582
ArrayList JavaDoc failedOnAllBackends = null;
1583      // List of controllers that have no more backends to execute queries
1584
ArrayList JavaDoc controllersWithoutBackends = null;
1585      SQLException JavaDoc exception = null;
1586      int size = groupMembers.size();
1587      boolean success = false;
1588      // Get the result of each controller
1589
for (int i = 0; i < size; i++)
1590      {
1591        Member member = (Member) groupMembers.get(i);
1592        if ((responses.getFailedMembers() != null)
1593            && responses.getFailedMembers().contains(member))
1594        {
1595          logger.warn("Controller " + member + " is suspected of failure.");
1596          continue;
1597        }
1598        Object JavaDoc r = responses.getResult(member);
1599        if (r instanceof Boolean JavaDoc)
1600        {
1601          if (((Boolean JavaDoc) r).booleanValue())
1602            success = true;
1603          else
1604            logger.error("Unexpected result for controller " + member);
1605        }
1606        else if (r instanceof AllBackendsFailedException)
1607        {
1608          if (failedOnAllBackends == null)
1609            failedOnAllBackends = new ArrayList JavaDoc();
1610          failedOnAllBackends.add(member);
1611          if (logger.isDebugEnabled())
1612            logger.debug("release savepoint failed on all backends of "
1613                + "controller " + member + " (" + r + ")");
1614        }
1615        else if (r instanceof NoMoreBackendException)
1616        {
1617          if (controllersWithoutBackends == null)
1618            controllersWithoutBackends = new ArrayList JavaDoc();
1619          controllersWithoutBackends.add(member);
1620          if (logger.isDebugEnabled())
1621            logger.debug("Controller " + member + " has no more backends to "
1622                + "release savepoint " + name + " from transaction "
1623                + transactionId + " (" + r + ")");
1624        }
1625        else if (r instanceof SQLException JavaDoc)
1626        {
1627          String JavaDoc msg = "release savepoint " + name + " from transaction "
1628              + transactionId + " failed on controller " + member + " (" + r
1629              + ")";
1630          logger.warn(msg);
1631          exception = (SQLException JavaDoc) r;
1632        }
1633      }
1634
1635      if (failedOnAllBackends != null)
1636      { // Notify all controllers where all backend failed that the rollback
1637
// completed with 'success'
1638
AbstractRequest request = new UnknownRequest("release " + name, false,
1639            0, "\n");
1640        request.setTransactionId(transactionId);
1641        try
1642        {
1643          dvdb.getMulticastRequestAdapter().multicastMessage(
1644              failedOnAllBackends, new NotifyCompletion(request, success),
1645              MulticastRequestAdapter.WAIT_NONE,
1646              CJDBCGroupMessage.defaultCastTimeOut);
1647        }
1648        catch (Exception JavaDoc e)
1649        {
1650          String JavaDoc msg = "An error occured while notifying all controllers of "
1651              + "failure to release savepoint " + name + " from transaction "
1652              + transactionId;
1653          logger.warn(msg, e);
1654          throw new SQLException JavaDoc(msg + " (" + e + ")");
1655        }
1656      }
1657
1658      if (success)
1659        return; // This is a success if at least one controller has succeeded
1660

1661      if (exception != null)
1662        throw exception;
1663
1664      // At this point, all controllers failed
1665

1666      if (controllersWithoutBackends != null)
1667      { // Notify all controllers without backend that have already logged the
1668
// request that they must remove it from the log
1669
int nbOfControllers = controllersWithoutBackends.size();
1670        for (int i = 0; i < nbOfControllers; i++)
1671        {
1672          Member member = (Member) controllersWithoutBackends.get(i);
1673          NoMoreBackendException nmbe = (NoMoreBackendException) responses
1674              .getResult(member);
1675          try
1676          {
1677            ArrayList JavaDoc dest = new ArrayList JavaDoc();
1678            dest.add(member);
1679            // Here we use the commit timeout field to transport the recovery
1680
// log id. This is ugly but convenient.
1681
dvdb.getMulticastRequestAdapter().multicastMessage(
1682                dest,
1683                new UnlogRollback(new TransactionMarkerMetaData(transactionId,
1684                    nmbe.getRecoveryLogId(), nmbe.getLogin())),
1685                MulticastRequestAdapter.WAIT_NONE,
1686                CJDBCGroupMessage.defaultCastTimeOut);
1687          }
1688          catch (Exception JavaDoc e)
1689          {
1690            String JavaDoc msg = "An error occured while notifying controllers "
1691                + member + " to unlog failed release savepoint " + name
1692                + " from transaction " + transactionId;
1693            logger.error(msg, e);
1694          }
1695        }
1696      }
1697
1698      if (exception != null)
1699        throw exception;
1700      else
1701      {
1702        String JavaDoc msg = "Release savepoint " + name + " from transaction "
1703            + transactionId + " failed on all controllers";
1704        logger.warn(msg);
1705        throw new SQLException JavaDoc(msg);
1706      }
1707    }
1708    catch (SQLException JavaDoc e)
1709    {
1710      String JavaDoc msg = "Release savepoint " + name + " from transaction "
1711          + transactionId + " failed (" + e + ")";
1712      logger.warn(msg);
1713      throw e;
1714    }
1715  }
1716}
Popular Tags