Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * JBoss, Home of Professional Open Source
    * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
    * as indicated by the @author tags. 
    * See the copyright.txt in the distribution for a
    * full listing of individual contributors. 
    * This copyrighted material is made available to anyone wishing to use,
    * modify, copy, or redistribute it subject to the terms and conditions
    * of the GNU Lesser General Public License, v. 2.1.
   * This program is distributed in the hope that it will be useful, but WITHOUT A 
   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
   * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
   * You should have received a copy of the GNU Lesser General Public License,
   * v.2.1 along with this distribution; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
   * MA  02110-1301, USA.
   * 
   * (C) 2005-2006,
   * @author JBoss Inc.
   */
  /*
   * Copyright (C) 1998, 1999, 2000, 2001,
   *
   * Arjuna Solutions Limited,
   * Newcastle upon Tyne,
   * Tyne and Wear,
   * UK.  
   *
   * $Id: BasicAction.java 2342 2006-03-30 13:06:17Z  $
   */
  
  package com.arjuna.ats.arjuna.coordinator;
  
  
BasicAction does most of the work of an atomic action, but does not manage thread scoping. This is the responsibility of any derived classes.

Author(s):
Mark Little (mark@arjuna.com)
Version:
$Id: BasicAction.java 2342 2006-03-30 13:06:17Z $
Since:
JTS 1.0.
  
  
  public class BasicAction extends StateManager
  {
  
      public BasicAction ()
      {
          super(.);
  
          if (..isTraceEnabled()) {
              ..trace("BasicAction::BasicAction()");
          }
  
           = null;
           = null;
           = null;
           = null;
           = null;
  
           = null;
           = null;
           = false;
  
           = .;
           = .;
  
           = null;
           = null;
  
  
           = null;
           = null;
      }

    
BasicAction constructor with a Uid. This constructor is for recreating an BasicAction, typically during crash recovery.
 
 
     public BasicAction (Uid objUid)
     {
         super(objUid.);
 
         if (..isTraceEnabled()) {
             ..trace("BasicAction::BasicAction("
                     + objUid + ")");
         }
 
          = null;
          = null;
          = null;
          = null;
          = null;
 
          = null;
          = null;
          = false;
 
          = .;
          = .;
 
          = null;
          = null;
 
 
          = null;
          = null;
     }

    
BasicAction destructor. Under normal circumstances we do very little. However there exists the possibility that this action is being deleted while still running (user forgot to commit/abort) - in which case we do an abort for him and mark all our parents as unable to commit. Additionally due to scoping we may not be the current action - but in that case the current action must be one of our nested actions so by applying abort to it we should end up at ourselves!
 
 
     public void finalizeInternal()
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::finalize()");
         }
 
         if (( == .)
                 || ( == .)) {
             /* If current action is one of my children there's an error */
 
             BasicAction currentAct = BasicAction.Current();
 
             if ((currentAct != null) && (currentAct != this)) {
                 /*
                      * Is the current action a child of this action? If so, abort
                      * until we get to the current action. This works even in a
                      * multi-threaded environment where each thread may have a
                      * different notion of current, since Current returns the thread
                      * specific current.
                      */
 
                 if (currentAct.isAncestor(get_uid())) {
                     ..warn_coordinator_BasicAction_1(get_uid());
 
                     while ((currentAct != this) && (currentAct != null)) {
                         ..warn_coordinator_BasicAction_2(currentAct.get_uid());
 
                         currentAct.Abort();
 
                         currentAct = BasicAction.Current();
                     }
                 }
             }
 
             BasicAction parentAct = parent();
 
             /* prevent commit of parents (safety) */
 
             while (parentAct != null) {
                 parentAct.preventCommit();
                 parentAct = parentAct.parent();
             }
 
 
             /* This will also kill any children */
 
             Abort();
         }
         else
         {
             if ( == .)
                 Thread.yield();
         }
 
          = null;
          = null;
          = null;
          = null;
          = null;
 
          = null;
          = null;
 
          = null;
 
         if ( != null)
         {
             .clear();
              = null;
         }
 
         if ( != null)
         {
             .clear();
              = null;
         }
     }

    
Return the action hierarchy for this transaction.
 
 
     public final synchronized ActionHierarchy getHierarchy ()
     {
         return ;
     }

    
Force the only outcome for the transaction to be to rollback. Only possible if this transaction has not (or is not) terminated.

Returns:
true if successful, false otherwise.
 
 
     public final boolean preventCommit ()
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::preventCommit( " + this + ")");
         }
 
         boolean res = false;
 
         //	if (lockMutex())
         {
             /*
                 * If we are active then change status. Otherwise it may be an error so check status.
                 */
 
             if ( == .)
                  = .;
 
             /*
                 * Since the reason to call this method is to make sure the transaction
                 * only aborts, check the status now and if it has aborted or will abort then
                 * we'll consider it a success.
                 */
 
             res = (( == .) || ( == .) || ( == .));
 
             //	    unlockMutex();
         }
 
         return res;
     }

    

Returns:
the number of threads associated with this transaction.
 
 
     public final int activeThreads ()
     {
         if ( != null)
             return .size();
         else
             return 0;
     }

    
Add a record to the atomic action. This function returns AR_ADDED if the record is added. AR_REJECTED if the record cannot be added because the action is past the prepare phase, and IGNORED otherwise.

Returns:
AddOutcome indicating outcome.
 
 
     public final synchronized int add (AbstractRecord A)
     {
         int result = .;
 
         criticalStart();
 
         if (( <= .)
                 && (( == null) || !(.equals(A))))
         {
             if ( == null)
                  = new RecordList();
 
             result = (.insert(A) ? .
                     : .);
         }
 
         criticalEnd();
 
         return result;
     }

    

Returns:
the depth of the current transaction hierarchy.
 
 
     public final synchronized int hierarchyDepth ()
     {
         if ( != null)
             return .depth();
         else
             return 0; /* should never happen */
     }

    
boolean function that checks whether the Uid passed as an argument is the Uid for an ancestor of the current atomic action.

Returns:
true if the parameter represents an ancestor, false otherwise.
 
 
     public final boolean isAncestor (Uid ancestor)
     {
         boolean res = false;
         
         if (get_uid().equals(ancestor)) /* actions are their own ancestors */
             res = true;
         else
         {
             if (( != null) && ( != .))
                 res = .isAncestor(ancestor);
         }
 
         return res;
     }

    

Returns:
a reference to the parent BasicAction
 
 
     public final BasicAction parent ()
     {
         if ( == .)
             return ;
         else
             return null;
     }
 
     public final int typeOfAction ()
     {
         return ;
     }

    

Returns:
the status of the BasicAction
 
 
     public final int status ()
     {
         int s = .;
 
         //	if (tryLockMutex())
         {
             s = ;
 
             //	    unlockMutex();
         }
 
         return s;
     }

    
Set up an object store and assign it to the participantStore variable.

Returns:
the object store implementation to use.
See also:
com.arjuna.ats.arjuna.objectstore.ObjectStore
 
 
     public ParticipantStore getStore ()
     {
         if ( == null)
         {
              = StoreManager.getParticipantStore();
         }
 
         return ;
     }

    
The following function returns the Uid of the top-level atomic action. If this is the top-level transaction then it is equivalent to calling get_uid().

Returns:
the top-level transaction's Uid.
 
 
     public final Uid topLevelActionUid ()
     {
         BasicAction root = this;
 
         while (root.parent() != null)
             root = root.parent();
 
         return root.get_uid();
     }

    

Returns:
a reference to the top-level transaction. If this is the top-level transaction then a reference to itself will be returned.
 
 
     public final BasicAction topLevelAction ()
     {
         BasicAction root = this;
 
         while (root.parent() != null)
             root = root.parent();
 
         return root;
     }

    
Overloaded version of activate -- sets up the store, performs read_state followed by restore_state. The store root is null.

Returns:
true if successful, false otherwise.
 
 
     public boolean activate ()
     {
         return activate(null);
     }

    
Overloaded version of activate -- sets up the store, performs read_state followed by restore_state. The root of the object store to use is specified in the root parameter.

Returns:
true if successful, false otherwise.
 
 
     public boolean activate (String root)
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::activate() for action-id "
                     + get_uid());
         }
 
         boolean restored = false;
 
         // Set up store
         ParticipantStore aaStore = getStore();
 
         if (aaStore == null)
             return false;
 
         try
         {
             // Read object state
 
             InputObjectState oState = aaStore.read_committed(getSavingUid(), type());
 
             if (oState != null)
             {
                 synchronized (this)
                 {
                     restored = restore_state(oState.);
                 }
 
                 oState = null;
             }
             else {
                 ..warn_coordinator_BasicAction_5(get_uid(), type());
 
                 restored = false;
             }
 
             return restored;
         }
         catch (ObjectStoreException e)
         {
             ..warn(e);
 
             return false;
         }
     }

    
This operation deactivates a persistent object. It behaves in a similar manner to the activate operation, but has an extra argument which defines whether the object's state should be committed or written as a shadow. The root of the object store is null. It is assumed that this is being called during a transaction commit.

Returns:
true on success, false otherwise.
 
 
     public boolean deactivate ()
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::deactivate() for action-id "
                     + get_uid());
         }
 
         boolean deactivated = false;
 
         // Set up store
         ParticipantStore aaStore = getStore();
 
         if (aaStore == null)
             return false;
 
         try
         {
             // Write object state
             OutputObjectState oState = new OutputObjectState();
 
             if (save_state(oState.))
             {
                 deactivated = aaStore.write_committed(getSavingUid(), type(), oState);
 
                 oState = null;
             }
             else
             {
                 deactivated = false;
             }

            
If we failed to deactivate then output warning *
 
             if (!deactivated) {
                 ..warn_coordinator_BasicAction_5a(get_uid(), type());
             }
         }
         catch (ObjectStoreException e)
         {
             ..warn(e);
 
             deactivated = false;
         }
 
         return deactivated;
     }

    
Add the current thread to the list of threads associated with this transaction.

Returns:
true if successful, false otherwise.
 
 
     public final boolean addChildThread () // current thread
     {
         return addChildThread(Thread.currentThread());
     }

    
Add the specified thread to the list of threads associated with this transaction.

Returns:
true if successful, false otherwise.
 
 
     public final boolean addChildThread (Thread t)
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::addChildThread () action "+get_uid()+" adding "+t);
         }
 
         if (t == null)
             return false;
 
         boolean result = false;
 
         criticalStart();
 
         synchronized (this)
         {
             if ( <= .)
             {
                 if ( == null)
                      = new Hashtable<StringThread>();
 
                 .put(ThreadUtil.getThreadId(t), t); // makes sure so we don't get
                 // duplicates
 
                 result = true;
             }
         }
 
         criticalEnd();
 
         if (..isTraceEnabled()) {
             ..trace("BasicAction::addChildThread () action "+get_uid()+" adding "+t+" result = "+result);
         }
 
         return result;
     }
 
     /*
       * Can be done at any time (Is this correct?)
       */

    
Remove a child thread. The current thread is removed.

Returns:
true if successful, false otherwise.
 
 
     public final boolean removeChildThread () // current thread
     {
         return removeChildThread(ThreadUtil.getThreadId());
     }

    
Remove the specified thread from the transaction.

Returns:
true if successful, false otherwise.
 
 
     public final boolean removeChildThread (String threadId)
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::removeChildThread () action "+get_uid()+" removing "+threadId);
         }
 
         if (threadId == null)
             return false;
 
         boolean result = false;
 
         criticalStart();
 
         synchronized (this)
         {
             if ( != null)
             {
                 .remove(threadId);
                 result = true;
             }
         }
 
         criticalEnd();
 
         if (..isTraceEnabled())
         {
             ..trace("BasicAction::removeChildThread () action "+get_uid()+" removing "+threadId+" result = "+result);
         }
 
         return result;
     }

    
Add a new child action to the atomic action.

Returns:
true if successful, false otherwise.
 
 
     public final boolean addChildAction (BasicAction act)
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::addAction () action "+get_uid()+" adding "+((act != null) ? act.get_uid() : Uid.nullUid()));
         }
 
         if (act == null)
             return false;
 
         boolean result = false;
 
         criticalStart();
 
         synchronized (this)
         {
             /*
                 * Must be <= as we sometimes need to do processing during commit
                 * phase.
                 */
 
             if ( <= .)
             {
                 if ( == null)
                      = new Hashtable<BasicActionBasicAction>();
 
                 .put(actact);
                 result = true;
             }
         }
 
         criticalEnd();
 
         if (..isTraceEnabled())
         {
             ..trace("BasicAction::addChildAction () action "+get_uid()+" adding "+act.get_uid()+" result = "+result);
         }
 
         return result;
     }
 
     /*
       * Can be done at any time (Is this correct?)
       */

    
Redefined version of save_state and restore_state from StateManager. Normal operation (no crashes): BasicAction.save_state is called after a successful prepare. This causes and BasicAction object to be saved in the object store. This object contains primarily the "intentions list" of the BasicAction. After successfully completing phase 2 of the commit protocol, the BasicAction object is deleted from the store. Failure cases: If a server crashes after successfully preparing, then upon recovery the action must be resolved (either committed or aborted) depending upon whether the co-ordinating atomic action committed or aborted. Upon server recovery, the crash recovery mechanism detects ServerBasicAction objects in the object store and attempts to activate the BasicAction object of the co-ordinating action. If this is successful then the SAA is committed else aborted. If, when processing phase 2 of the commit protocol, the co-ordinator experiences a failure to commit from one of the records then the BasicAction object is NOT deleted. It is rewritten when a new state which contains a list of the records that failed during phase 2 commit. This list is called the "failedList". The crash recovery manager will detect local BasicAction objects in addition to SAA objects in the objectstore. An attempt will be made to commit these actions. If the action contained a call to a now dead server, this action can never be resolved and the AA object can never be removed. However, if the action is purely local then after the processing is complete the removed by crash recovery.

Returns:
true if successful, false otherwise.
 
 
     public boolean save_state (OutputObjectState osint ot)
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::save_state ()");
         }
 
         try
         {
             packHeader(osnew Header(get_uid(), Utility.getProcessUid()));
             
             os.packBoolean();
         }
         catch (IOException e)
         {
             return false;
         }
 
         /*
            * In a presumed abort scenario, this routine is called: a) After a
            * successful prepare - to save the intentions list. b) After a failure
            * during phase 2 of commit - to overwrite the intentions list by the
            * failedList.
            *
            * If we're using presumed nothing, then it could be called: a) Whenever
            * a participant is registered.
            */
 
         RecordList listToSave = null;
         boolean res = true;
 
         /*
            * If we have a failedList then we are re-writing a BasicAction object
            * after a failure during phase 2 commit
            */
 
         if (( != null) && (.size() > 0))
         {
             listToSave = ;
         }
         else
         {
             listToSave = ;
         }
 
         AbstractRecord first = ((listToSave != null) ? listToSave.getFront()
                 : null);
         AbstractRecord temp = first;
         boolean havePacked = ((listToSave == null) ? false : true);
 
         while ((res) && (temp != null))
         {
             listToSave.putRear(temp);
 
             /*
                 * First check to see if we need to call save_state. If we do then
                 * we must first save the record type (and enum) and then save the
                 * unique identity of the record (a string). The former is needed to
                 * determine what type of record we are restoring, while the latter
                 * is required to re-create the actual record.
                 */
 
             /*
                 * First check to see if we need to call save_state. If we do then
                 * we must first save the record type. This is used to determine
                 * which type of record to create when restoring.
                 */
 
             if (..isTraceEnabled())
             {
                 ..trace("BasicAction::save_state - next record to pack is a "+temp.typeIs()
                         +" record "+temp.type()+" should save it? = "+temp.doSave());
             }
 
             if (temp.doSave())
             {
                 res = true;
 
                 try
                 {
                     if (..isTraceEnabled()) {
                         ..trace("Packing a "+temp.typeIs()+" record");
                     }
 
                     os.packInt(temp.typeIs());
                     res = temp.save_state(osot);
                 }
                 catch (IOException e)
                 {
                     res = false;
                 }
             }
 
             temp = listToSave.getFront();
 
             if (temp == first)
             {
                 listToSave.putFront(temp);
                 temp = null;
             }
         }
 
         /*
            * If we only ever had a heuristic list (e.g., one-phase commit) then
            * pack a record delimiter.
            */
 
         if (res && (os.notempty() || !havePacked))
         {
             try
             {
                 if (..isTraceEnabled()) {
                     ..trace("Packing a NONE_RECORD");
                 }
 
                 os.packInt(.);
             }
             catch (IOException e)
             {
                 res = false;
             }
         }
 
         if (res)
         {
             // Now deal with anything on the heuristic list!
 
             int hSize = (( == null) ? 0 : .size());
 
             try
             {
                 os.packInt(hSize);
             }
             catch (IOException e)
             {
                 res = false;
             }
 
             if (res && (hSize > 0))
             {
                 first = .getFront();
                 temp = first;
 
                 while (res && (temp != null))
                 {
                     .putRear(temp);
 
                     if (temp.doSave())
                     {
                         res = true;
 
                         try
                         {
                             if (..isTraceEnabled()) {
                                 ..trace("HeuristicList - packing a "+temp.typeIs()+" record");
                             }
 
                             os.packInt(temp.typeIs());
                             res = temp.save_state(osot);
                         }
                         catch (IOException e)
                         {
                             res = false;
                         }
                     }
 
                     temp = .getFront();
 
                     if (temp == first)
                     {
                         .putFront(temp);
                         temp = null;
                     }
                 }
 
                 if (res && os.notempty())
                 {
                     try
                     {
                         if (..isTraceEnabled()) {
                             ..trace("HeuristicList - packing a NONE_RECORD");
                         }
 
                         os.packInt(.);
                     }
                     catch (IOException e)
                     {
                         res = false;
                     }
                 }
             }
         }
 
         if (res && os.notempty())
         {
             try
             {
                 if (..isTraceEnabled()) {
                     ..trace("Packing action status of "+ActionStatus.stringForm());
                 }
 
                 os.packInt();
                 os.packInt(); // why pack since only top-level?
                 os.packInt(); // can we optimize?
             }
             catch (IOException e)
             {
                 res = false;
             }
         }
 
         return res;
     }

    
Remove a child action.

Returns:
true if successful, false otherwise.
 
 
     public final boolean removeChildAction (BasicAction act)
     {
         if (..isTraceEnabled()) {
             ..trace("BasicAction::removeChildAction () action "+get_uid()+" removing "+((act != null) ? act.get_uid() : Uid.nullUid()));
         }
 
         if (act == null)
             return false;
 
         boolean result = false;
 
         criticalStart();
 
         synchronized (this)
         {
             if ( != null)
            {
                .remove(act);
                result = true;
            }
        }
        criticalEnd();
        if (..isTraceEnabled())
        {
            ..trace("BasicAction::removeChildAction () action "+get_uid()+" removing "+act.get_uid()+" result = "+result);
        }
        return result;
    }

    
Add the specified CheckedAction object to this transaction.

See also:
CheckedAction
    protected final synchronized void setCheckedAction (CheckedAction c)
    {
        criticalStart();
         = c;
        criticalEnd();
    }

    

Returns:
the Uid that the transaction's intentions list will be saved under.
    public Uid getSavingUid ()
    {
        return get_uid();
    }

    
Overloads Object.toString()
    public String toString ()
    {
        return new String("BasicAction: " + get_uid() + " status: "
                + ActionStatus.stringForm());
    }

    
This assumes the various lists are zero length when it is called.

Returns:
true if successful, false otherwise.
    public boolean restore_state (InputObjectState osint ot)
    {
        if (..isTraceEnabled()) {
            ..trace("BasicAction::restore_state ()");
        }
        createPreparedLists();
        boolean res = true;
        int record_type = .;
        int tempActionStatus = .;
        int tempActionType = .;
        int tempHeuristicDecision = .;
        /*
           * Unpack the prepared list. Note: This may either be a full intentions
           * list or just the failedList, either way, restore it as the prepared
           * list.
           */
        try
        {
            Header hdr = new Header();
            unpackHeader(oshdr);
            
             = os.unpackBoolean();
        }
        catch (IOException e)
        {
            return false;
        }
        try
        {
            record_type = os.unpackInt();
            if (..isTraceEnabled()) {
                ..trace("Unpacked a "+record_type+" record");
            }
        }
        catch (IOException e)
        {
            res = false;
        }
        while ((res) && (record_type != .))
        {
            AbstractRecord record = AbstractRecord.create(record_type);
            if (record == null) {
                ..warn_coordinator_BasicAction_21(Integer.toString(record_type));
                res = false;
            }
            else
                res = (record.restore_state(osot) && .insert(record));
            if (res)
            {
                try
                {
                    record_type = os.unpackInt();
                    if (..isTraceEnabled()) {
                        ..trace("Unpacked a "+record_type+" record");
                    }
                }
                catch (IOException e)
                {
                    res = false;
                }
            }
        }
        // Now deal with the heuristic list!
        int hSize = 0;
        if (res)
        {
            try
            {
                hSize = os.unpackInt();
                if (..isTraceEnabled()) {
                    ..trace("HeuristicList - Unpacked heuristic list size of "+hSize);
                }
            }
            catch (IOException e)
            {
                res = false;
            }
        }
        if (hSize > 0)
        {
            try
            {
                record_type = os.unpackInt();
                if (..isTraceEnabled()) {
                    ..trace("HeuristicList - Unpacked a "+record_type+" record");
                }
            }
            catch (IOException e)
            {
                res = false;
            }
            while ((res) && (record_type != .))
            {
                AbstractRecord record = AbstractRecord.create(record_type);
                try
                {
                    res = (record.restore_state(osot) && .insert(record));
                    record_type = os.unpackInt();
                    if (..isTraceEnabled()) {
                        ..trace("HeuristicList - Unpacked a "+record_type+" record");
                    }
                }
                catch (IOException e)
                {
                    res = false;
                }
                catch (final NullPointerException ex) {
                    ..warn_coordinator_norecordfound(Integer.toString(record_type));
                    res = false;
                }
            }
        }
        if (res)
        {
            try
            {
                tempActionStatus = os.unpackInt();
                tempActionType = os.unpackInt();
                tempHeuristicDecision = os.unpackInt();
            }
            catch (IOException e) {
                ..warn_coordinator_BasicAction_24();
                res = false;
            }
        }
        if (res)
        {
            if (..isTraceEnabled()) {
                ..trace("Restored action status of "+ActionStatus.stringForm(tempActionStatus)+
                        " "+Integer.toString(tempActionStatus));
                ..trace("Restored action type "+
                        ((tempActionType == .) ? "Nested" : "Top-level")+
                        " "+Integer.toString(tempActionType));
                ..trace(" Restored heuristic decision of "+
                        TwoPhaseOutcome.stringForm(tempHeuristicDecision)+" "+Integer.toString(tempHeuristicDecision));
            }
             = tempActionStatus;
             = tempActionType;
             = tempHeuristicDecision;
             = true;
        }
        return res;
    }

    
Overloads StateManager.type()
    public String type ()
    {
        return "/StateManager/BasicAction";
    }

    

Returns:
the thread's notion of the current transaction.
    public static BasicAction Current ()
    {
        return ThreadActionData.currentAction();
    }

    
If heuristic outcomes are returned, by default we will not save the state once the forget method has been called on them (which happens as soon as we have received all outcomes from registered resources). By specifying otherwise, we will always maintain the heuristic information, which may prove useful for logging and off-line resolution.

Returns:
true if the transaction should save its heuristic information, false otherwise.
    public static boolean maintainHeuristics ()
    {
        return .;
    }

    
Overloads StateManager.destroy to prevent destroy being called on a BasicAction. Could be a *very* bad idea!!

Returns:
false.
See also:
com.arjuna.ats.arjuna.StateManager
    public boolean destroy ()
    {
        return true;
    }

    

Returns:
the list of child transactions. Currently only their ids are given.
Since:
JTS 2.2.
    public final Object[] childTransactions ()
    {
        int size = (( == null) ? 0 : .size());
        if (size > 0)
        {
            Collection<BasicActionc = .values();
            return c.toArray();
        }
        return null;
    }
    @Override
    public boolean equals (java.lang.Object obj)
    {
        if (obj instanceof BasicAction)
        {
            if (((BasicActionobj).get_uid().equals(get_uid()))
                return true;
        }
        return false;
    }
    @Override
    public int hashCode()
    {
        return get_uid().hashCode();
    }

    
Forget any heuristics we may have received, and tell the resources which generated them to forget too.

Returns:
true if heuristic information (if any) was successfully forgotten, false otherwise.
    protected boolean forgetHeuristics ()
    {
        if (( != null) && (.size() > 0))
        {
            doForget();
            updateState();
            if (.size() == 0)
                return true;
            else
                return false;
        }
        else
            return true;
    }

    
Atomic action Begin operation. Does not change the calling thread's notion of the current transaction.

Returns:
ActionStatus indicating outcome.
    protected synchronized int Begin (BasicAction parentAct)
    {
        if (