KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jts > CosTransactions > RegisteredResources


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28 //----------------------------------------------------------------------------
29
//
30
// Module: RegisteredResources.java
31
//
32
// Description: Transaction participant management.
33
//
34
// Product: com.sun.jts.CosTransactions
35
//
36
// Author: Simon Holdsworth
37
//
38
// Date: March, 1997
39
//
40
// Copyright (c): 1995-1997 IBM Corp.
41
//
42
// The source code for this program is not published or otherwise divested
43
// of its trade secrets, irrespective of what has been deposited with the
44
// U.S. Copyright Office.
45
//
46
// This software contains confidential and proprietary information of
47
// IBM Corp.
48
//----------------------------------------------------------------------------
49

50 package com.sun.jts.CosTransactions;
51
52 import java.util.*;
53
54 import org.omg.CORBA.*;
55 import org.omg.CosTransactions.*;
56
57 import com.sun.jts.otsidl.*;
58 import com.sun.jts.trace.*;
59 import com.sun.jts.jtsxa.OTSResourceImpl;
60 import java.util.logging.Logger JavaDoc;
61 import java.util.logging.Level JavaDoc;
62 import com.sun.logging.LogDomains;
63 import com.sun.jts.utils.LogFormatter;
64
65 import javax.transaction.xa.*;
66 /**
67  * The RegisteredResources class provides operations that manage a list
68  * of Resource objects involved in a transaction, and their states relative
69  * to the transaction. Resource references are stored in lists as there is no
70  * way to perform Resource reference comparisons. As an instance of this
71  * class may be accessed from multiple threads within a process,
72  * serialisation for thread-safety is necessary in the implementation.
73  * The information recorded in an instance of this class needs to be
74  * reconstructible in the case of a system failure.
75  *
76  * @version 0.02
77  *
78  * @author Simon Holdsworth, IBM Corporation
79  *
80  * @see
81  */

82
83 //----------------------------------------------------------------------------
84
// CHANGE HISTORY
85
//
86
// Version By Change Description
87
// 0.01 SAJH Initial implementation.
88
// 0.02 GDH Gordon Hutchison April 1998
89
// Added OBLECT_NOT_EXIST as an allowable exception in
90
// distribute rollback.
91
//----------------------------------------------------------------------------
92

93 class RegisteredResources {
94     private ArrayList resourceObjects = null;
95     private ArrayList resourceStates = null;
96     private CoordinatorLog logRecord = null;
97     private java.lang.Object JavaDoc logSection = null;
98     private java.lang.Object JavaDoc heuristicLogSection = null;
99     private Resource laoResource = null;
100     private CoordinatorImpl coord = null;
101     private static boolean lastXAResCommit = false;
102     // START IASRI 4662745
103
//private int commitRetries = -1;
104
// private static int commitRetries = -1;
105
// END IASRI 4662745
106

107     //introduced for performance - remembers ths number of registered resources
108
private int nRes=0;
109
110     // private static String commitRetryVar =
111
// Configuration.getPropertyValue(Configuration.COMMIT_RETRY);
112

113     // private final static long COMMIT_RETRY_WAIT = 60000; // moved to Configuration.java
114
private final static String JavaDoc LOG_SECTION_NAME = "RR"/*#Frozen*/;
115     private final static String JavaDoc HEURISTIC_LOG_SECTION_NAME = "RRH"/*#Frozen*/;
116
117     static {
118         String JavaDoc lastXAResCommitProp = System.getProperty("com.sun.jts.lastagentcommit");
119         if (lastXAResCommitProp != null && "true".equals(lastXAResCommitProp.toLowerCase())) {
120             lastXAResCommit = true;
121         }
122     }
123     
124     /*
125         Logger to log transaction messages
126     */

127         static Logger JavaDoc _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER);
128     /**
129      * Defines the CoordinatorLog which is to be used for recovery.
130      * <p>
131      * The CoordinatorLog for the transaction is updated with empty sections
132      * for RegisteredResources and RegisteredResourcesHeuristic created.
133      * <p>
134      * Initialises the list of RegisteredResources to be empty.
135      * <p>
136      * The CoordinatorLog is used as the basis for recovering the
137      * RegisteredResources and RegisteredResourcesHeuristic information at
138      * restart.
139      *
140      * @param log The CoordinatorLog object for the transaction.
141      *
142      * @return
143      *
144      * @see
145      */

146     RegisteredResources(CoordinatorLog log, CoordinatorImpl coord) {
147
148         resourceObjects = new ArrayList();
149         resourceStates = new ArrayList();
150
151         // Create two sections in the CoordinatorLog object for Resources.
152

153         logRecord = log;
154
155         if (log != null) {
156
157             // Create section for Resources registered as part of transaction
158

159           // logSection = log.createSection(LOG_SECTION_NAME);
160

161             // Create section for Resources with heuristic actions taken
162

163           // heuristicLogSection = log.createSection(HEURISTIC_LOG_SECTION_NAME);
164
}
165         this.coord = coord;
166     }
167
168     /**
169      * Default RegisteredResources constructor.
170      *
171      * @param
172      *
173      * @return
174      *
175      * @see
176      */

177     RegisteredResources(CoordinatorImpl coord) { this.coord = coord;}
178
179     /**
180      * Cleans up RegisteredResources state.
181      *
182      * @param
183      *
184      * @return
185      *
186      * @see
187      */

188     public void finalize() {
189
190         if (resourceObjects != null) {
191           empty();
192         }
193
194         resourceObjects = null;
195         resourceStates = null;
196         logRecord = null;
197         logSection = null;
198         heuristicLogSection = null;
199     }
200
201     /**
202      * Directs the RegisteredResources to recover its state after a failure.
203      * <p>
204      * This is based on the given CoordinatorLog object. The participant list
205      * and heuristic information is reconstructed.
206      *
207      * @param log The CoordinatorLog holding the RegisteredResources state.
208      *
209      * @return
210      *
211      * @see
212      */

213
214     void reconstruct(CoordinatorLog log) {
215
216
217         // Set up the instance variables.
218

219         resourceObjects = new ArrayList();
220         resourceStates = new ArrayList();
221         boolean infiniteRetry = true;
222
223         // First, get the retry count.
224

225         /**
226         if (commitRetries == -1 && commitRetryVar != null) {
227             try {
228                 commitRetries = Integer.parseInt(commitRetryVar);
229             } catch (Throwable e) {}
230
231             infiniteRetry = false;
232         }
233         **/

234         int commitRetries = Configuration.getRetries();
235         if (commitRetries >= 0)
236             infiniteRetry = false;
237
238         // Reconstruct our state from CoordinatorLog object.
239

240         // Get the Registered Resources and the Registered Resources that had
241
// Heuristic results. Return the list of Registered Resources that did
242
// not have any Heuristic results.
243

244         heuristicLogSection = log.createSection(HEURISTIC_LOG_SECTION_NAME);
245         java.lang.Object JavaDoc[] resources = log.getObjects(heuristicLogSection);
246         for(int i = 0; i < resources.length; i++) {
247             boolean exceptionThrown=true;
248             int commitRetriesLeft = commitRetries;
249             while(exceptionThrown){
250                 try {
251                     Resource res =
252                         ResourceHelper.narrow((org.omg.CORBA.Object JavaDoc)resources[i]);
253                     if (res != null) {
254                         resourceObjects.add(res);
255             nRes++;
256                         resourceStates.add(ResourceStatus.Heuristic);
257                     }
258             exceptionThrown=false;
259                 } catch (Throwable JavaDoc exc) {
260                      if(exc instanceof TRANSIENT || exc instanceof COMM_FAILURE) {
261                          // If the exception is either TRANSIENT or
262
// COMM_FAILURE, keep retrying
263

264                          //$ CHECK WITH DSOM FOLKS FOR OTHER EXCEPTIONS
265
_logger.log(Level.WARNING,"jts.exception_on_resource_operation",
266                                        new java.lang.Object JavaDoc[]{exc.toString(),
267                                        "reconstruct"});
268                          if (commitRetriesLeft > 0 || infiniteRetry) {
269
270                              // For TRANSIENT or COMM_FAILURE, wait
271
// for a while, then retry the commit.
272
if (!infiniteRetry) {
273                                  commitRetriesLeft--;
274                              }
275
276                              try {
277                                  Thread.sleep(Configuration.COMMIT_RETRY_WAIT);
278                              } catch( Throwable JavaDoc e ) {}
279
280                          } else {
281
282                              // If the retry limit has been exceeded,
283
// end the process with a fatal error.
284
_logger.log(Level.SEVERE,"jts.retry_limit_exceeded",
285                                      new java.lang.Object JavaDoc[] {
286                                      new Integer JavaDoc(commitRetries), "commit"});
287                              String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
288                                                         "jts.retry_limit_exceeded",
289                                                          new java.lang.Object JavaDoc[] {
290                                                          new Integer JavaDoc(commitRetries), "commit"});
291                               throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
292                             //exceptionThrown=false;
293
//Commented out code as this statement is not
294
//reachable
295
}
296                     }
297                     else{
298                         exceptionThrown=false;
299                    }
300                }
301             }
302         }
303
304         // Resources that did not have Heuristic outcomes are added to the list
305
// Get section id for Resources registered as part of transaction
306

307         logSection = log.createSection(LOG_SECTION_NAME);
308         resources = log.getObjects(logSection);
309         for (int i = 0; i < resources.length; i++) {
310             boolean exceptionThrown=true;
311             int commitRetriesLeft = commitRetries;
312             while(exceptionThrown){
313                 try {
314                     Resource res =
315                         ResourceHelper.narrow((org.omg.CORBA.Object JavaDoc)resources[i]);
316                     if (res != null) {
317                         resourceObjects.add(res);
318             nRes++;
319                         resourceStates.add(ResourceStatus.Registered);
320                     }
321             exceptionThrown=false;
322                 } catch (Throwable JavaDoc exc) {
323                      if(exc instanceof TRANSIENT || exc instanceof COMM_FAILURE) {
324                          // If the exception is either TRANSIENT or
325
// COMM_FAILURE, keep retrying
326

327                          //$ CHECK WITH DSOM FOLKS FOR OTHER EXCEPTIONS
328
_logger.log(Level.WARNING,"jts.exception_on_resource_operation",
329                                 new java.lang.Object JavaDoc[] {exc.toString(),"reconstruct"});
330                          if (commitRetriesLeft > 0 || infiniteRetry) {
331
332                              // For TRANSIENT or COMM_FAILURE, wait
333
// for a while, then retry the commit.
334
if (!infiniteRetry) {
335                                  commitRetriesLeft--;
336                              }
337
338                              try {
339                                  Thread.sleep(Configuration.COMMIT_RETRY_WAIT);
340                              } catch( Throwable JavaDoc e ) {}
341
342                          } else {
343
344                              // If the retry limit has been exceeded,
345
// end the process with a fatal error.
346
_logger.log(Level.SEVERE,"jts.retry_limit_exceeded",
347                                      new java.lang.Object JavaDoc[] {new Integer JavaDoc(commitRetries),
348                                                             "commit"});
349                              String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
350                                                         "jts.retry_limit_exceeded",
351                                                          new java.lang.Object JavaDoc[] {
352                                                          new Integer JavaDoc(commitRetries),
353                                                             "commit"});
354                                     
355                               throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
356                            // exceptionThrown=false;
357
//Commented out as this will not be executed
358
}
359                     }
360                     else{
361                         exceptionThrown=false;
362                    }
363                }
364
365            }
366        }
367
368         logRecord = log;
369     }
370     /**
371      * Adds a reference to a Resource object to the list in the
372      * registered state.
373      *
374      * @param obj The reference of the Resource object to be stored.
375      *
376      * @return The number of registered Resource objects.
377      *
378      * @see
379      */

380     int addRes(Resource obj) {
381
382         //int result;
383

384         // Add the reference to the list (which was created when this object
385
// was created), with the "registered" status.
386

387         resourceObjects.add(obj);
388     nRes++;
389         resourceStates.add(ResourceStatus.Registered);
390         //result =nRes;
391

392         // Dont add the reference to the log record at this point
393
// as it may vote read-only.
394

395         return nRes;
396     }
397
398     /**
399      * Empties the list of registered Resources.
400      *
401      * @param
402      *
403      * @return
404      *
405      * @see
406      */

407     void empty() {
408
409         // Empty the list of all Resource references.
410

411         resourceObjects.clear();
412     nRes=0;
413         resourceStates.clear();
414     }
415
416     /**
417      * Checks whether there are any Resource objects registered.
418      * <p>
419      * If there are, the operation returns true, otherwise false.
420      *
421      * @param
422      *
423      * @return Indicates whether any Resources registered.
424      *
425      * @see
426      */

427     boolean involved() {
428
429         boolean result = (nRes != 0 );
430
431         return result;
432     }
433
434     /**
435      * Returns the number of Resources currently in the list.
436      *
437      * @param
438      *
439      * @return The number of registered Resources.
440      *
441      * @see
442      */

443     int numRegistered() {
444
445         return nRes;
446     }
447
448     /**
449      * Distributes prepare messages to all Resources in the registered state.
450      * <p>
451      * Resource objects that vote to commit the transaction are added to the
452      * RegisteredResources section in the CoordinatorLog.
453      * <p>
454      * All Resources that return VoteReadOnly have their state set to
455      * completed. The consolidated result is returned.
456      *
457      * @param
458      *
459      * @return The vote for the transaction.
460      *
461      * @exception HeuristicMixed Indicates that a participant voted
462      * to roll the transaction back, but one or more others have
463      * already heuristically committed.
464      * @exception HeuristicHazard Indicates that a participant voted to
465      * roll the transaction back, but one or more others may have
466      * already heuristically committed.
467      *
468      * @see
469      */

470     Vote distributePrepare() throws HeuristicMixed, HeuristicHazard {
471         boolean isProxy = false;
472         Vote result = Vote.VoteReadOnly;
473         int laoIndex = -1;
474
475         // Browse through the participants, preparing them, and obtain
476
// a consolidated result. The following is intended to be done
477
// asynchronously as a group of perations, however if done
478
// sequentially, it should stop after the first rollback vote.
479
// If there are no Resource references, return the a read-only vote.
480

481         for (int i = 0;
482                 i < nRes && result != Vote.VoteRollback;
483                 i++) {
484
485             Resource currResource = (Resource) resourceObjects.get(i);
486
487             if ((i == nRes - 1) && lastXAResCommit && (laoResource == null) &&
488                 result == Vote.VoteCommit) {
489                 try {
490                     if(_logger.isLoggable(Level.FINER))
491                     {
492                         _logger.logp(Level.FINER,"RegisteredResources",
493                             "distributePrepare()",
494                             "Before invoking commit on LA resource = " +
495                             currResource);
496                     }
497                     currResource.commit_one_phase();
498                     resourceStates.set(i, ResourceStatus.Completed);
499                     if(_logger.isLoggable(Level.FINER))
500                     {
501                         _logger.logp(Level.FINER,"RegisteredResources",
502                             "distributePrepare()",
503                             "After invoking commit on LA resource = "+
504                             currResource);
505                     }
506                 } catch (Throwable JavaDoc exc) {
507                     result = Vote.VoteRollback;
508                     resourceStates.set(i,ResourceStatus.Completed);
509                 }
510                 return result;
511             }
512
513             // We determine here whether the object is subordinate or proxy
514
// because the object may not exist when the prepare returns.
515

516             //String crid = CoordinatorResourceHelper.id();
517
//boolean isSubordinate = currResource._is_a( crid );
518

519             // COMMENT(Ram J) the instanceof operation should be replaced
520
// by a is_local() call, once the local object contract is
521
// implemented.
522
if(!(currResource instanceof OTSResourceImpl)) {
523               ProxyChecker checkProxy = Configuration.getProxyChecker();
524               isProxy = checkProxy.isProxy(currResource);
525             }
526
527             Vote currResult = Vote.VoteRollback;
528
529             try {
530                 if(_logger.isLoggable(Level.FINER))
531                 {
532                     _logger.logp(Level.FINER,"RegisteredResources","prepare()",
533                             "Before invoking prepare() on resource:" +
534                             currResource);
535                 }
536                 currResult = currResource.prepare();
537                 //Mark this resource as LA if vote is null
538
if(currResult == null) {
539                     if(_logger.isLoggable(Level.FINER))
540                     {
541                 _logger.logp(Level.FINER,"RegisteredResources","prepare()",
542                     "Marking the current resource as LAO:" +
543                      currResource);
544                     }
545                     laoResource = currResource;
546                     laoIndex = i;
547                     continue;
548                 }
549         if(_logger.isLoggable(Level.FINER))
550                 {
551             _logger.logp(Level.FINER,"RegisteredResources","prepare()",
552                     "After invoking prepare() on resource:" +
553                  currResource + ";This resource voted : "+
554                  currResult);
555                 }
556             } catch (Throwable JavaDoc exc) {
557
558                 // If a heuristic exception is thrown, this is because the
559
// Resource represents a subordinate which is voting to
560
// rollback; one of its Resources voted to roll back after
561
// others had voted to commit, and one of the commit voters
562
// then raised a heuristic exception when told to roll back.
563
// In this situation, we need to go back through all Resources
564
// and try to roll them back, not including the one
565
// which raised the exception.
566

567                 boolean hazard = exc instanceof HeuristicHazard;
568                 if (exc instanceof HeuristicMixed || hazard) {
569
570                     // Mark the Resource which threw the exception as
571
// heuristic so that we do not
572
// try to roll it back, but we do send it a forget.
573

574                     resourceStates.set(i,ResourceStatus.Heuristic);
575
576                     try {
577                         distributeRollback(true);
578                     } catch (Throwable JavaDoc ex2) {
579
580                         // If the rollback threw an exception, change
581
// HeuristicHazard to HeuristicMixed if necessary.
582

583                         if (ex2 instanceof HeuristicMixed && hazard) {
584                             hazard = false;
585                         }
586                     }
587
588                     // Now throw the appropriate exception.
589

590                     if (hazard) {
591                         HeuristicHazard ex2 = new HeuristicHazard();
592                         throw ex2;
593                     } else {
594                         HeuristicMixed ex2 = new HeuristicMixed();
595                         throw ex2;
596                     }
597                 }
598
599                 // If any other exception is raised, assume the vote
600
// is rollback.
601
//$Check for specific exceptions ?
602
_logger.log(Level.WARNING,"jts.exception_on_resource_operation",
603                         new java.lang.Object JavaDoc[] {exc.toString(),"prepare"});
604             }
605
606             // Record the outcome from the participant
607

608             // Take an action depending on the participant's vote.
609

610             if (currResult == Vote.VoteCommit) {
611                 if (logRecord != null) {
612                     if (!(currResource instanceof OTSResourceImpl)) {
613                         if (logSection == null)
614                             logSection = logRecord.createSection(LOG_SECTION_NAME);
615                         logRecord.addObject(logSection, currResource);
616                     }
617                 }
618
619                 if (result == Vote.VoteReadOnly) {
620                     result = Vote.VoteCommit;
621                 }
622             } else {
623
624                 // If a participant votes readonly, don't change the overall
625
// vote. If a participant votes to rollback the transaction,
626
// change the consolidated result to rollback.
627
// Dont bother writing the reference to the log.
628
// The state of the Resource object is set
629
// to completed as we must not call it after it has voted
630
// to rollback the transaction. Set the state of a participant
631
// that votes read-only to completed as it
632
// replies. The consolidated vote does not change.
633

634                 resourceStates.set(i,ResourceStatus.Completed);
635                 if (isProxy) {
636                     currResource._release();
637                 }
638
639                 if (currResult == Vote.VoteRollback) {
640                     result = currResult;
641                 }
642             }
643         }
644
645         if (result == Vote.VoteCommit && laoResource != null) {
646             try {
647         if(_logger.isLoggable(Level.FINER))
648                 {
649             _logger.logp(Level.FINER,"RegisteredResources",
650                      "distributePrepare()",
651                      "Before invoking commit on LA resource = " +
652                      laoResource);
653                 }
654                 // laoResource.commit();
655
resourceStates.set(laoIndex, ResourceStatus.Completed);
656         if(_logger.isLoggable(Level.FINER))
657                 {
658             _logger.logp(Level.FINER,"RegisteredResources",
659                      "distributePrepare()",
660                      "After invoking commit on LA resource = "+
661                      laoResource);
662                 }
663             } catch (Throwable JavaDoc exc) {
664                 result = Vote.VoteRollback;
665                 resourceStates.set(laoIndex,ResourceStatus.Completed);
666             }
667         }
668         return result;
669     }
670     
671     Resource getLAOResource() {
672         return laoResource;
673     }
674     
675     
676
677     /**
678      * Distributes commit messages to all Resources in the registered state
679      * <p>
680      * (i.e. not including those that voted VoteReadOnly). All Resources that
681      * return successfully have their state set to completed; those that
682      * raise heuristic exceptions are added to the
683      * RegisteredResourcesHeuristic section of the CoordinatorLog and have
684      * their state set to heuristic.
685      * <p>
686      * All Resources in the heuristic state are then told to forget,
687      * their state is set to completed, and the CoordinatorLog object
688      * is forced to the physical log.
689      *
690      * @param
691      *
692      * @return
693      *
694      * @exception HeuristicMixed Indicates that heuristic decisions have been
695      * taken which have resulted in part of the transaction
696      * being rolled back.
697      * @exception HeuristicHazard Indicates that heuristic decisions may have
698      * been taken which have resulted in part of the transaction
699      * being rolled back.
700      *
701      * @see
702      */

703     void distributeCommit() throws HeuristicMixed, HeuristicHazard, NotPrepared {
704         boolean infiniteRetry = true;
705         boolean isProxy = false;
706
707         boolean heuristicException = false;
708         boolean heuristicMixed = false;
709
710         // First, get the retry count.
711

712         /**
713         if (commitRetries == -1 && commitRetryVar != null) {
714             try {
715                 commitRetries = Integer.parseInt(commitRetryVar);
716             } catch (Throwable e) {}
717
718             infiniteRetry = false;
719         }
720         **/

721         int commitRetries = Configuration.getRetries();
722         if (commitRetries >= 0)
723             infiniteRetry = false;
724
725
726         // Browse through the participants, committing them. The following is
727
// intended to be done asynchronously as a group of operations.
728

729         boolean transactionCompleted = true;
730         String JavaDoc msg = null;
731         for (int i = 0; i < nRes; i++) {
732
733             Resource currResource = (Resource) resourceObjects.get(i);
734
735             // If the current Resource in the browse is not in the registered
736
// state, skip over it.
737

738             if ((ResourceStatus) resourceStates.get(i) ==
739                     ResourceStatus.Registered) {
740
741                 boolean heuristicRaised = false;
742
743                 // We determine here whether the object is a proxy because the
744
// object may not exist when the commit returns.
745

746                 // COMMENT(Ram J) the instanceof operation should be replaced
747
// by a is_local() call, once the local object contract is
748
// implemented.
749
if(!(currResource instanceof com.sun.jts.jtsxa.OTSResourceImpl)) {
750                     ProxyChecker checkProxy = Configuration.getProxyChecker();
751                     isProxy = checkProxy.isProxy(currResource);
752                 }
753
754                 // Change the current Resource's state to completing.
755

756                 resourceStates.set(i,ResourceStatus.Completing);
757
758                 // Tell the resource to commit.
759
// Catch any exceptions here; keep going until
760
// no exception is left.
761

762                 int commitRetriesLeft = commitRetries;
763                 boolean exceptionThrown = true;
764                 while (exceptionThrown) {
765                     try {
766                         if(_logger.isLoggable(Level.FINER))
767                         {
768                             _logger.logp(Level.FINER,"RegisteredResources",
769                                     "distributeCommit()",
770                                     "Before invoking commit on resource = " +
771                                     currResource);
772                         }
773                         currResource.commit();
774                         if(_logger.isLoggable(Level.FINER))
775                         {
776                             _logger.logp(Level.FINER,"RegisteredResources",
777                                     "distributeCommit()",
778                                     "After invoking commit on resource = "+
779                                     currResource);
780                         }
781                         exceptionThrown = false;
782                     } catch (Throwable JavaDoc exc) {
783
784                         if (exc instanceof HeuristicCommit) {
785
786                             // If the exception is Heuristic Commit, remember
787
// that a heuristic exception has been raised.
788
heuristicException = true;
789                             heuristicRaised = true;
790                             exceptionThrown = false;
791
792                         } else if (exc instanceof HeuristicRollback ||
793                                    exc instanceof HeuristicHazard ||
794                                    exc instanceof HeuristicMixed) {
795                             // If the exception is Heuristic Rollback,
796
// Mixed or Hazard, remember that a heuristic
797
// exception has been raised, and also that
798
// damage has occurred.
799

800                             heuristicException = true;
801                             heuristicMixed = !(exc instanceof HeuristicHazard);
802                             heuristicRaised = true;
803                             exceptionThrown = false;
804
805                         } else if (exc instanceof INV_OBJREF ||
806                                    exc instanceof OBJECT_NOT_EXIST) {
807
808                             // If the exception is INV_OBJREF, then the target
809
// Resource object must have already committed.
810
exceptionThrown = false;
811
812                         } else if (exc instanceof NotPrepared) {
813
814                             // If the exception is NotPrepared, then the target
815
// Resource has not recorded the fact that it has
816
// been called for prepare, or some internal glitch
817
// has happened inside the RegisteredResources /
818
// TopCoordinator. In this case the only sensible
819
// action is to end the process with a fatal error
820
// message.
821
_logger.log(Level.SEVERE,
822                                     "jts.exception_on_resource_operation",
823                                      new java.lang.Object JavaDoc[] {exc.toString(),"commit"});
824                             
825                              throw (NotPrepared)exc;
826                              /**
827                              msg = LogFormatter.getLocalizedMessage(_logger,
828                                                 "jts.exception_on_resource_operation",
829                                                 new java.lang.Object[] {exc.toString(),
830                                                 "commit"});
831                              throw new org.omg.CORBA.INTERNAL(msg);
832                              **/

833                         } else if (!(exc instanceof TRANSIENT) &&
834                                    !(exc instanceof COMM_FAILURE)) {
835                             // If the exception is neither TRANSIENT or
836
// COMM_FAILURE, it is unexpected, so display a
837
// message and give up with this Resource.
838

839                             //$ CHECK WITH DSOM FOLKS FOR OTHER EXCEPTIONS
840
_logger.log(Level.SEVERE,
841                                     "jts.exception_on_resource_operation",
842                                      new java.lang.Object JavaDoc[] {exc.toString(),"commit"});
843                             
844                              exceptionThrown = false;
845                              transactionCompleted = false;
846                              msg = LogFormatter.getLocalizedMessage(_logger,
847                                                 "jts.exception_on_resource_operation",
848                                                 new java.lang.Object JavaDoc[] {exc.toString(),
849                                                 "commit"});
850
851                         } else if (commitRetriesLeft > 0 || infiniteRetry) {
852
853                             // For TRANSIENT or COMM_FAILURE, wait
854
// for a while, then retry the commit.
855
if (!infiniteRetry) {
856                                 commitRetriesLeft--;
857                             }
858
859                             try {
860                                 Thread.sleep(Configuration.COMMIT_RETRY_WAIT);
861                             } catch( Throwable JavaDoc e ) {}
862
863                         } else {
864
865                             // If the retry limit has been exceeded,
866
// end the process with a fatal error.
867
_logger.log(Level.SEVERE,"jts.retry_limit_exceeded",
868                                    new java.lang.Object JavaDoc[] {
869                                    new Integer JavaDoc(commitRetries), "commit"});
870
871                              exceptionThrown = false;
872                              transactionCompleted = false;
873                              msg = LogFormatter.getLocalizedMessage(_logger,
874                                                     "jts.retry_limit_exceeded",
875                                                     new java.lang.Object JavaDoc[] {
876                                                     new Integer JavaDoc(commitRetries), "commit"});
877                         }
878                     }
879                 }
880
881
882                 if (heuristicRaised) {
883
884                     // Either mark the participant as having raised a heuristic
885
// exception, or as completed.
886

887                     resourceStates.set(i,ResourceStatus.Heuristic);
888
889                     if (logRecord != null) {
890                         if (!(currResource instanceof OTSResourceImpl)) {
891                             if (heuristicLogSection == null)
892                                 heuristicLogSection =
893                                         logRecord.createSection(HEURISTIC_LOG_SECTION_NAME);
894                             logRecord.addObject(heuristicLogSection, currResource);
895                         }
896                     }
897                 } else {
898
899                     // If completed, and the object is a proxy,
900
// release the proxy now.
901

902                     resourceStates.set(i,ResourceStatus.Completed);
903                     if (isProxy) {
904                         currResource._release();
905                     }
906                 }
907             }
908         }
909
910         // The browse is complete.
911
// If a heuristic exception was raised, perform forget processing. This
912
// will then throw the appropriate heuristic exception to the caller.
913

914         if (heuristicException)
915           distributeForget(commitRetries, infiniteRetry, heuristicMixed);
916
917         if (!transactionCompleted) {
918             if (coord != null)
919                 RecoveryManager.addToIncompleTx(coord, true);
920             if (msg != null)
921                 throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
922             else
923                 throw new org.omg.CORBA.INTERNAL JavaDoc();
924         }
925
926         // Otherwise just return normally.
927
}
928
929     /**
930      * Distributes rollback messages to all Resources in the registered state.
931      * <p>
932      * (i.e. not including those that voted VoteReadOnly). All Resources that
933      * return successfully have their state set to completed; those that raise
934      * heuristic exceptions are added to the RegisteredResourcesHeuristic
935      * section of the CoordinatorLog and have their state set to heuristic.
936      * <p>
937      * All Resources in the heuristic state are then told to forget,
938      * their state is set to completed, and the CoordinatorLog object
939      * is forced to the physical log.
940      *
941      * @param heuristicException Indicates that a heuristic exception has
942      * already been thrown for this transaction, and that forget
943      * processing should proceed.
944      *
945      * @return
946      *
947      * @exception HeuristicMixed Indicates that heuristic decisions have been
948      * taken which have resulted in part of the transaction
949      * being rolled back.
950      * @exception HeuristicHazard Indicates that heuristic decisions
951      * may have been taken which have resulted in part of the transaction
952      * being rolled back.
953      *
954      * @see
955      */

956     void distributeRollback(boolean heuristicException)
957             throws HeuristicMixed, HeuristicHazard {
958
959         boolean infiniteRetry = true;
960         boolean heuristicMixed = false;
961         boolean isProxy = false;
962
963         // First, get the retry count.
964

965         /**
966         if (commitRetries == -1 && commitRetryVar != null) {
967
968             try {
969                 commitRetries = Integer.parseInt(commitRetryVar);
970             } catch (Throwable e) {}
971
972             infiniteRetry = false;
973         }
974         **/

975         int commitRetries = Configuration.getRetries();
976         if (commitRetries >= 0)
977             infiniteRetry = false;
978
979
980
981         // Browse through the participants, committing them. The following is
982
// intended to be done asynchronously as a group of operations.
983

984         boolean transactionCompleted = true;
985         String JavaDoc msg = null;
986         for (int i = 0; i < nRes; i++) {
987
988             Resource currResource = (Resource)resourceObjects.get(i);
989
990             // If the current Resource in the browse is not in the registered
991
// state, skip over it.
992

993             if (resourceStates.get(i).equals(
994                     ResourceStatus.Registered)) {
995                 boolean heuristicRaised = false;
996
997                 // We determine here whether the object is a proxy because
998
// the object may not exist when the commit returns.
999

1000                // COMMENT(Ram J) the instanceof operation should be replaced
1001
// by a is_local() call, once the local object contract is
1002
// implemented.
1003
if (!(currResource instanceof com.sun.jts.jtsxa.OTSResourceImpl)) {
1004                    ProxyChecker checkProxy = Configuration.getProxyChecker();
1005                    isProxy = checkProxy.isProxy(currResource);
1006                }
1007
1008                // Change the current Resource's state to completing.
1009

1010                resourceStates.set(i,ResourceStatus.Completing);
1011
1012                // Tell the resource to commit.
1013
// Catch any exceptions here; keep going
1014
// until no exception is left.
1015

1016                int rollbackRetriesLeft = commitRetries;
1017                boolean exceptionThrown = true;
1018                while (exceptionThrown) {
1019                    try {
1020                        if(_logger.isLoggable(Level.FINER))
1021                        {
1022                            _logger.logp(Level.FINER,"RegisteredResources",
1023                                    "distributeRollback()",
1024                                    "Before invoking rollback on resource = "+
1025                                    currResource);
1026                        }
1027                        currResource.rollback();
1028                        if(_logger.isLoggable(Level.FINER))
1029                        {
1030                            _logger.logp(Level.FINER,"RegisteredResources",
1031                                    "distributeRollback()",
1032                                    "After invoking rollback on resource = "+
1033                                    currResource);
1034                        }
1035                        exceptionThrown = false;
1036                    } catch (Throwable JavaDoc exc) {
1037
1038                        if (exc instanceof TRANSACTION_ROLLEDBACK) {
1039
1040                            // If the exception is TRANSACTION_ROLLED back,
1041
// then continue.
1042
exceptionThrown = false;
1043                        }
1044
1045                        if (exc instanceof HeuristicRollback) {
1046
1047                            // If the exception is Heuristic Rollback,
1048
// remember that a heuristic exception
1049
// has been raised.
1050
heuristicException = true;
1051                            heuristicRaised = true;
1052                            exceptionThrown = false;
1053
1054                        } else if (exc instanceof HeuristicCommit ||
1055                                   exc instanceof HeuristicHazard ||
1056                                   exc instanceof HeuristicMixed) {
1057
1058                            // If the exception is Heuristic Rollback, Mixed
1059
// or Hazard, remember that a heuristic exception
1060
// has been raised, and also that damage has
1061
// occurred.
1062
heuristicException = true;
1063                            heuristicMixed = !(exc instanceof HeuristicHazard);
1064                            heuristicRaised = true;
1065                            exceptionThrown = false;
1066
1067                        } else if (exc instanceof INV_OBJREF ||
1068                                   exc instanceof OBJECT_NOT_EXIST){
1069
1070                            //GDH added NOT_EXIST
1071
// If the exception is INV_OBJREF, then the target
1072
// Resource object must have already rolled back.
1073
exceptionThrown = false;
1074
1075                        } else if (!(exc instanceof TRANSIENT) &&
1076                                   !(exc instanceof COMM_FAILURE)) {
1077
1078                            // If the exception is neither TRANSIENT or
1079
// COMM_FAILURE, it is unexpected, so display
1080
// a message and give up with this Resource.
1081
_logger.log(Level.SEVERE,
1082                                    "jts.exception_on_resource_operation",
1083                                     new java.lang.Object JavaDoc[]
1084                                          { exc.toString(), "rollback"});
1085
1086                              msg = LogFormatter.getLocalizedMessage(_logger,
1087                                            "jts.exception_on_resource_operation",
1088                                           new java.lang.Object JavaDoc[] { exc.toString(),
1089                                                "rollback"});
1090                              exceptionThrown = false;
1091                              transactionCompleted = false;
1092
1093                        } else if (rollbackRetriesLeft > 0 || infiniteRetry) {
1094
1095                            // For TRANSIENT or COMM_FAILURE, wait for a while,
1096
// then retry the rollback.
1097

1098                            if (!infiniteRetry) {
1099                                rollbackRetriesLeft--;
1100                            }
1101
1102                            try {
1103                                Thread.sleep(Configuration.COMMIT_RETRY_WAIT);
1104                            } catch( Throwable JavaDoc e ) {}
1105
1106                        } else {
1107
1108                            // If the retry limit has been exceeded, end the
1109
// process with a fatal error.
1110
_logger.log(Level.SEVERE,"jts.retry_limit_exceeded",
1111                                    new java.lang.Object JavaDoc[]
1112                                    { new Integer JavaDoc(commitRetries), "rollback"});
1113
1114                            msg = LogFormatter.getLocalizedMessage(_logger,
1115                                                "jts.retry_limit_exceeded",
1116                                                new java.lang.Object JavaDoc[]
1117                                                { new Integer JavaDoc(commitRetries), "rollback"});
1118                                                
1119                            exceptionThrown = false;
1120                            transactionCompleted = false;
1121                        }
1122                    }
1123                }
1124
1125                if (heuristicRaised) {
1126
1127                    // Either mark the participant as having raised a
1128
// heuristic exception, or as completed.
1129

1130                    resourceStates.set(i,ResourceStatus.Heuristic);
1131                    if (logRecord != null) {
1132                        if (!(currResource instanceof OTSResourceImpl)) {
1133                            if (heuristicLogSection == null)
1134                                heuristicLogSection =
1135                                        logRecord.createSection(HEURISTIC_LOG_SECTION_NAME);
1136
1137                            logRecord.addObject(heuristicLogSection,currResource);
1138                        }
1139                    }
1140
1141                } else {
1142
1143                    // If completed, and the object is a proxy,
1144
// release the proxy now.
1145

1146                    resourceStates.set(i,ResourceStatus.Completed);
1147                    if (isProxy) {
1148                        currResource._release();
1149                    }
1150                }
1151            }
1152        }
1153
1154
1155        // The browse is complete.
1156
// If a heuristic exception was raised, perform forget processing.
1157
// This will then throw the appropriate heuristic exception
1158
// to the caller.
1159

1160        if (heuristicException)
1161            distributeForget(commitRetries, infiniteRetry, heuristicMixed);
1162
1163        if (!transactionCompleted) {
1164            if (coord != null)
1165                RecoveryManager.addToIncompleTx(coord, false);
1166            if (msg != null)
1167                throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
1168            else
1169                throw new org.omg.CORBA.INTERNAL JavaDoc();
1170        }
1171
1172        // Otherwise just return normally.
1173
}
1174
1175    /**
1176     * Distributes forget messages to all Resources in the heuristic state.
1177     * <p>
1178     * (i.e. only those which have thrown heuristic exceptions on prepare,
1179     * commit or rollback).
1180     * <p>
1181     * All Resources then have their state set to completed.
1182     *
1183     * @param retries The number of times to retry the forget operation.
1184     * @param infinite indicates infinite retry.
1185     *
1186     * @return
1187     *
1188     * @exception HeuristicMixed Indicates that heuristic decisions have been
1189     * taken which have resulted in part of the transaction
1190     * being rolled back.
1191     * @exception HeuristicHazard Indicates that heuristic decisions may have
1192     * been taken which have resulted in part of the transaction being
1193     * rolled back.
1194     *
1195     * @see
1196     */

1197    private void distributeForget(int retries, boolean infinite,
1198            boolean heuristicMixed) throws HeuristicMixed, HeuristicHazard {
1199
1200        boolean isProxy = false;
1201
1202        // Force the log record to ensure that all
1203
// heuristic Resources are logged.
1204

1205        if (logRecord != null) {
1206            logRecord.write(true);
1207        }
1208
1209        // Browse through the remaining participants, informing them that they
1210
// may forget the heuristic information at this point
1211

1212        for (int i = 0; i < nRes; i++) {
1213
1214            // If the current Resource in the browse is not in the heuristic
1215
// state, skip over it.
1216

1217            if ((ResourceStatus)resourceStates.get(i) ==
1218                    ResourceStatus.Heuristic) {
1219
1220                Resource currResource = (Resource)resourceObjects.get(i);
1221
1222                // We determine here whether the object is a proxy because
1223
// the object may not exist when the forget returns.
1224

1225                // COMMENT(Ram J) the instanceof operation should be replaced
1226
// by a is_local() call, once the local object contract is
1227
// implemented.
1228
if(!(currResource instanceof com.sun.jts.jtsxa.OTSResourceImpl)) {
1229                    ProxyChecker checkProxy = Configuration.getProxyChecker();
1230                    isProxy = checkProxy.isProxy(currResource);
1231                }
1232
1233                // Tell the resource to forget.
1234

1235                int retriesLeft = retries;
1236                boolean exceptionThrown = true;
1237                while (exceptionThrown) {
1238                    try {
1239                        currResource.forget();
1240                        exceptionThrown = false;
1241                    } catch (Throwable JavaDoc exc) {
1242
1243                        if (exc instanceof INV_OBJREF ||
1244                                exc instanceof OBJECT_NOT_EXIST) {
1245
1246                            // If the exception is INV_OBJREF, then the target
1247
// Resource object must have already forgotten.
1248
exceptionThrown = false;
1249
1250                        } else if (!(exc instanceof COMM_FAILURE) &&
1251                                   !(exc instanceof TRANSIENT)) {
1252
1253                            // If the exception is neither TRANSIENT or
1254
// COMM_FAILURE, it is unexpected, so display
1255
// a message and give up with this Resource.
1256
//$ CHECK WITH DSOM FOLKS FOR OTHER EXCEPTIONS
1257
exceptionThrown = false;
1258
1259                        } else if (retriesLeft > 0 || infinite) {
1260
1261                            // For TRANSIENT or COMM_FAILURE, wait for a while,
1262
// then retry the forget.
1263
if (!infinite) {
1264                                retriesLeft--;
1265                            }
1266
1267                            try {
1268                                Thread.sleep(Configuration.COMMIT_RETRY_WAIT);
1269                            } catch( Throwable JavaDoc e ) {}
1270
1271                        } else {
1272
1273                            // If the retry limit has been exceeded,
1274
// end the process with a fatal error.
1275
_logger.log(Level.SEVERE,"jts.retry_limit_exceeded",
1276                                    new java.lang.Object JavaDoc[] { new Integer JavaDoc(retries),
1277                                    "forget"});
1278                             String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
1279                                                    "jts.retry_limit_exceeded",
1280                                                    new java.lang.Object JavaDoc[]
1281                                                    { new Integer JavaDoc(retries), "forget"});
1282                              throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
1283                        }
1284                    }
1285                }
1286
1287                // Set the state of the Resource to completed
1288
// after a successful forget. If the
1289
// Resource is a proxy, release the reference.
1290

1291                resourceStates.set(i,ResourceStatus.Completed);
1292                if (isProxy) {
1293                    currResource._release();
1294                }
1295            }
1296        }
1297
1298        // If the original commit or rollback threw a HeuristicHazard
1299
// or HeuristicMixed exception was raised, throw it now.
1300

1301        if (heuristicMixed) {
1302            HeuristicMixed exc = new HeuristicMixed();
1303            throw exc;
1304        } else {
1305            HeuristicHazard exc = new HeuristicHazard();
1306            throw exc;
1307        }
1308    }
1309
1310    /**
1311     * Distributes commitSubtransaction messages to all registered
1312     * SubtransactionAwareResources.
1313     *
1314     * @param parent The parent's Coordinator reference.
1315     *
1316     * @return
1317     *
1318     * @exception TRANSACTION_ROLLEDBACK The subtransaction could not be
1319     * committed. Some participants may have committed and some may have
1320     * rolled back.
1321     *
1322     * @see
1323     */

1324    void distributeSubcommit(Coordinator parent)
1325            throws TRANSACTION_ROLLEDBACK {
1326
1327        boolean exceptionRaised = false;
1328        boolean isProxy = false;
1329
1330        // Browse through the participants, committing them. The following is
1331
// intended to be done asynchronously as a group of operations.
1332

1333        for (int i = 0; i < nRes; i++) {
1334
1335            SubtransactionAwareResource currResource =
1336                (SubtransactionAwareResource)resourceObjects.get(i);
1337
1338            // COMMENT(Ram J) the instanceof operation should be replaced
1339
// by a is_local() call, once the local object contract is
1340
// implemented.
1341
if(!(currResource instanceof com.sun.jts.jtsxa.OTSResourceImpl)) {
1342                ProxyChecker checkProxy = Configuration.getProxyChecker();
1343                isProxy = checkProxy.isProxy(currResource);
1344            }
1345
1346           // Tell the object to commit.
1347

1348            try {
1349                currResource.commit_subtransaction(parent);
1350            } catch (Throwable JavaDoc exc) {
1351
1352                // Check for exceptions.
1353
// If the TRANSACTION_ROLLEDBACK exception was raised,
1354
// remember it.
1355

1356                if (exc instanceof TRANSACTION_ROLLEDBACK) {
1357                    exceptionRaised = true;
1358                }
1359            }
1360
1361            // Change the state of the object.
1362

1363            resourceStates.set(i,ResourceStatus.Completed);
1364
1365            // If the Resource is a proxy, release it.
1366

1367            if (isProxy) {
1368                currResource._release();
1369            }
1370        }
1371
1372        // If an exception was raised, return it to the caller.
1373

1374        if (exceptionRaised) {
1375            throw new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_YES);
1376        }
1377    }
1378
1379    /**
1380     * Distributes rollbackSubtransaction messages to all registered
1381     * SubtransactionAwareResources.
1382     *
1383     * @param
1384     *
1385     * @return
1386     *
1387     * @see
1388     */

1389    void distributeSubrollback() {
1390        boolean isProxy = false;
1391
1392        // Browse through the participants, rolling them back. The following is
1393
// intended to be done asynchronously as a group of operations.
1394

1395
1396        for (int i = 0; i < nRes; i++) {
1397            SubtransactionAwareResource currResource =
1398                (SubtransactionAwareResource) resourceObjects.get(i);
1399
1400            // COMMENT(Ram J) the instanceof operation should be replaced
1401
// by a is_local() call, once the local object contract is
1402
// implemented.
1403
if(!(currResource instanceof com.sun.jts.jtsxa.OTSResourceImpl)) {
1404                ProxyChecker checkProxy = Configuration.getProxyChecker();
1405                isProxy = checkProxy.isProxy(currResource);
1406            }
1407
1408            // Tell the object to roll back.
1409

1410            try {
1411                currResource.rollback_subtransaction();
1412            } catch (Throwable JavaDoc exc) {}
1413
1414            resourceStates.set(i,ResourceStatus.Completed);
1415
1416            // If the Resource is a proxy, release it.
1417

1418            if (isProxy) {
1419                currResource._release();
1420            }
1421        }
1422    }
1423
1424    /**
1425     * Fills in the given Vector objects with the currently registered Resource
1426     * objects and their corresponding states.
1427     *
1428     * @param resources The object to hold the objects.
1429     * @param states The object to hold the states.
1430     *
1431     * @return
1432     *
1433     * @see
1434     */

1435    /* COMMENT(Ram J) - we do not support Admin package anymore.
1436    void getResources(ResourceSequenceHolder resources,
1437                      ResourceStatusSequenceHolder states) {
1438
1439        resources.value = new Resource[resourceObjects.size()];
1440        states.value = new ResourceStatus[resourceObjects.size()];
1441
1442        resourceObjects.copyInto(resources.value);
1443        resourceStates.copyInto(states.value);
1444    }
1445    */

1446
1447    /**
1448     * Distributes the one phase commit.
1449     *
1450     * @param none
1451     *
1452     * @return void
1453     *
1454     * @see
1455     */

1456    void commitOnePhase() throws HeuristicMixed, HeuristicHazard {
1457
1458        boolean infiniteRetry = true;
1459
1460        boolean heuristicRaisedSetStatus = false;
1461        boolean heuristicExceptionFlowForget = false;
1462        boolean isProxy = false;
1463
1464        boolean heuristicMixed = false;
1465        boolean heuristicHazard = false;
1466        boolean rollback_occurred = false;
1467        boolean outstanding_resources = true;
1468        int retry_limit;
1469        int no_of_attempts;
1470
1471        // First, get the retry count.
1472

1473        /**
1474        if (commitRetries == -1 && commitRetryVar != null) {
1475            try {
1476                commitRetries = Integer.parseInt(commitRetryVar);
1477            } catch (Throwable exc) {
1478                _logger.log(Level.SEVERE,"jts.exception_on_resource_operation",
1479                    new java.lang.Object[]
1480                        { exc.toString(), "CommitOnePhase commitRetryVar" });
1481                
1482                 String msg = LogFormatter.getLocalizedMessage(_logger,
1483                                        "jts.exception_on_resource_operation",
1484                                        new java.lang.Object[]
1485                                        { exc.toString(), "CommitOnePhase commitRetryVar" });
1486                  throw new org.omg.CORBA.INTERNAL(msg);
1487            }
1488            infiniteRetry = false;
1489        }
1490        **/

1491        int commitRetries = Configuration.getRetries();
1492        if (commitRetries >= 0)
1493            infiniteRetry = false;
1494
1495
1496        // Check we only have one resource!
1497
// If not return
1498
if (nRes > 1) {
1499            _logger.log(Level.SEVERE,"jts.exception_on_resource_operation",
1500                    new java.lang.Object JavaDoc[] { "commitOnePhase", ">1 Resource"});
1501             String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
1502                                        "jts.exception_on_resource_operation",
1503                                        new java.lang.Object JavaDoc[]
1504                                        { "commitOnePhase", ">1 Resource"});
1505             throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
1506        }
1507
1508        // Now we know we have one resource we can use similar
1509
// logic to the 'commit' method
1510

1511        Resource currResource = (Resource) resourceObjects.get(0);
1512
1513        // If the single resource is not in the registered state,
1514
// we can return too!
1515
// (Ram Jeyaraman) Should this condition check be != and then return ?
1516
// Previously the IF block had '==' operator and empty block
1517
if ((ResourceStatus) resourceStates.get(0) !=
1518                ResourceStatus.Registered) {
1519            return;
1520        }
1521
1522        // We determine here whether the object is a proxy because
1523
// the object may not exist when the commit returns.
1524

1525        // COMMENT(Ram J) the instanceof operation should be replaced
1526
// by a is_local() call, once the local object contract is
1527
// implemented.
1528
if(!(currResource instanceof com.sun.jts.jtsxa.OTSResourceImpl)) {
1529            ProxyChecker checkProxy = Configuration.getProxyChecker();
1530            isProxy = checkProxy.isProxy(currResource);
1531        }
1532
1533        // Change the current Resource's state to completing.
1534

1535        resourceStates.set(0,ResourceStatus.Completing);
1536
1537        // Tell the resource to commit.
1538
// Catch any exceptions here; keep going until no exception is left.
1539

1540        int commitRetriesLeft = commitRetries;
1541
1542        boolean exceptionThrownTryAgain = true;
1543
1544        while (exceptionThrownTryAgain) {
1545            try {
1546                if(_logger.isLoggable(Level.FINEST))
1547                {
1548                    _logger.logp(Level.FINEST,"RegisteredResources","commitOnePhase()",
1549                            "Before invoking commit_one_phase() on resource:" +
1550                            currResource );
1551                }
1552
1553                currResource.commit_one_phase();
1554
1555                if(_logger.isLoggable(Level.FINEST))
1556                {
1557                    _logger.logp(Level.FINEST,"RegisteredResources","commitOnePhase()",
1558                            "After invoking commit_one_phase() on resource:" +
1559                            currResource );
1560                }
1561                resourceStates.set(0,ResourceStatus.Completed);
1562                exceptionThrownTryAgain = false;
1563            } catch (Throwable JavaDoc exc) {
1564
1565                if (exc instanceof TRANSACTION_ROLLEDBACK) {
1566                    //
1567
// The resource rolled back - remember this.
1568
//
1569
rollback_occurred = true;
1570                    resourceStates.set(0,ResourceStatus.Completed);
1571                    exceptionThrownTryAgain = false;
1572
1573                } else if (exc instanceof HeuristicHazard) {
1574
1575                    // If the exception is Heuristic Rollback,
1576
// Mixed or Hazard, remember that a heuristic exception
1577
// has been raised, and also that damage has occurred.
1578

1579                        
1580                        //IASRI START 4722883
1581
/**
1582                        heuristicExceptionFlowForget = true;
1583                        heuristicRaisedSetStatus = true;
1584                        exceptionThrownTryAgain = false;
1585                        heuristicMixed = false;
1586                        **/

1587                        XAException e = (XAException) ((Throwable JavaDoc)exc).getCause();
1588                        if ((e!= null) && (e.errorCode >= XAException.XA_RBBASE && e.errorCode <= XAException.XA_RBEND)) {
1589                            rollback_occurred = true;
1590                            resourceStates.set(0,ResourceStatus.Completed);
1591                            exceptionThrownTryAgain = false;
1592                        }
1593                        else {
1594                            heuristicExceptionFlowForget = true;
1595                            heuristicRaisedSetStatus = true;
1596                            exceptionThrownTryAgain = false;
1597                            heuristicMixed = false;
1598                        }
1599                        //IASRI END 4722883
1600

1601
1602                } else if (exc instanceof INV_OBJREF ||
1603                        exc instanceof OBJECT_NOT_EXIST) {
1604
1605                    // If the exception is INV_OBJREF, then the target Resource
1606
// object must have already committed. (Probably contacted
1607
// the resource on a previous attempt but its OK response
1608
// was lost due to a failure.)
1609

1610                    resourceStates.set(0,ResourceStatus.Completed);
1611                    exceptionThrownTryAgain = false;
1612
1613                } else if (exc instanceof NotPrepared) {
1614
1615                    // If the exception is NotPrepared, then the target
1616
// Resource is probably trying to indicate that it does not
1617
// support one phase commit. Considered switching to
1618
// 2PC commit for a retry here but as commit one phase is
1619
// part of our specification then something is fishy
1620
// if it is not supported: Throw an error.
1621
_logger.log(Level.SEVERE,"jts.exception_on_resource_operation",
1622                            new java.lang.Object JavaDoc[] { exc.toString(),
1623                            "commit one phase"});
1624                     String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
1625                                                "jts.exception_on_resource_operation",
1626                                                new java.lang.Object JavaDoc[] { exc.toString(),
1627                                                "commit one phase"});
1628                     throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
1629
1630                } else if (!(exc instanceof TRANSIENT) &&
1631                        !(exc instanceof COMM_FAILURE)) {
1632
1633                    // If the exception has not been mentione yet and is
1634
// neither of the two below, it is unexpected,
1635
// so display a message and give up with this Resource.
1636
_logger.log(Level.SEVERE,"jts.exception_on_resource_operation",
1637                            new java.lang.Object JavaDoc[] { exc.toString(),
1638                            "commit one phase"});
1639                     String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
1640                                                "jts.exception_on_resource_operation",
1641                                                new java.lang.Object JavaDoc[] { exc.toString(),
1642                                                "commit one phase"});
1643                     throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
1644
1645                } else if (commitRetriesLeft > 0 || infiniteRetry) {
1646
1647                     // For TRANSIENT or COMM_FAILURE, wait for a while,
1648
// then retry the commit.
1649
if (!infiniteRetry) {
1650                        commitRetriesLeft--;
1651                    }
1652
1653                    try {
1654                        Thread.sleep(Configuration.COMMIT_RETRY_WAIT);
1655                    } catch (Throwable JavaDoc e) {}
1656
1657                } else {
1658
1659                    // If the retry limit has been exceeded, end the
1660
// process with a fatal error.
1661
// GDH Did consider carefully here whether the exception
1662
// should be perculated back to the client. With 2PC
1663
// because we can take action on the other resources we
1664
// carry on and subsequently pass an exception to the
1665
// client. But here there is little point in doing
1666
// this as all recoverable work has either
1667
// been done or not by this point - we have a
1668
// serious problem so stop now. If the JTS was built
1669
// into an application server (rather than being a
1670
// toolkit for standalone apps) then we would replace
1671
// all the FATAL_ERROR actions such as the one below
1672
// with the actino required by the application server.
1673
_logger.log(Level.SEVERE,"jts.retry_limit_exceeded",
1674                            new java.lang.Object JavaDoc[] { new Integer JavaDoc(commitRetries),
1675                            "commitOnePhase"});
1676                     String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
1677                                            "jts.retry_limit_exceeded",
1678                                             new java.lang.Object JavaDoc[] {
1679                                             new Integer JavaDoc(commitRetries),"commitOnePhase"});
1680                      throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
1681                }
1682            } // end of catch block for exceptions
1683
} // end while exception being raised (GDH)
1684

1685        // Either mark the participant as having raised a heuristic exception,
1686
// or as completed.
1687

1688        if (heuristicRaisedSetStatus) {
1689            resourceStates.set(0,ResourceStatus.Heuristic);
1690            if (logRecord != null) {
1691                // (The distributeForget method forces the log)
1692
if (!(currResource instanceof OTSResourceImpl)) {
1693                    if (heuristicLogSection == null)
1694                        heuristicLogSection =
1695                            logRecord.createSection(HEURISTIC_LOG_SECTION_NAME);
1696                    logRecord.addObject(heuristicLogSection,currResource);
1697                }
1698            }
1699        } else {
1700            // Otherwise we are completed, if the object is a proxy,
1701
// release the proxy now.
1702

1703            resourceStates.set(0,ResourceStatus.Completed);
1704            if (isProxy) {
1705                currResource._release();
1706            }
1707        }
1708
1709        // If a heuristic exception was raised, perform forget processing.
1710
// This will then throw the appropriate heuristic exception
1711
// to the caller.
1712

1713        if (heuristicExceptionFlowForget) {
1714          distributeForget(commitRetries, infiniteRetry, heuristicMixed);
1715          // throw is done in method above
1716
}
1717
1718        if (rollback_occurred) {
1719            throw new TRANSACTION_ROLLEDBACK(0,
1720                                             CompletionStatus.COMPLETED_YES);
1721        }
1722
1723        // Otherwise just return normally.
1724
}
1725
1726    // START IASRI 4662745
1727
/**
1728    public static void setCommitRetryVar(String commitRetryString)
1729    {
1730            if (commitRetries == -1 && commitRetryVar != null) {
1731            try {
1732                commitRetries = Integer.parseInt(commitRetryVar);
1733            } catch (Exception e) {}
1734        }
1735    }
1736    **/

1737    // END IASRI 4662745
1738
}
1739
1740
Popular Tags