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: StateManager.java 2342 2006-03-30 13:06:17Z  $
   */
  
  package com.arjuna.ats.arjuna;
  
  
The root of the Arjuna class hierarchy. This class provides state management facilities than can be automatically used by other classes by inheritance.

Author(s):
Mark Little (mark@arjuna.com)
Version:
$Id: StateManager.java 2342 2006-03-30 13:06:17Z $
Since:
JTS 1.0.
  
  
  public class StateManager
  {

    
These methods must be used by a derived class. They are responsible for packing and unpacking an object's state to/from a state buffer. StateManager calls them at appropriate times during the lifetime of the object, and may then pass the buffer to a persistent object store for saving.

Returns:
true on success, false otherwise.
  
  
      public synchronized boolean save_state (OutputObjectState osint ot)
      {
          /*
           * Only pack additional information if this is for a persistent state
           * modification.
           */
  
          if (ot == .)
          {
              try
              {
                  BasicAction action = BasicAction.Current();
 
                 if (action == null)
                     packHeader(osnew Header(null, Utility.getProcessUid()));
                 else
                     packHeader(osnew Header(action.get_uid(), Utility.getProcessUid()));
             }
             catch (IOException e)
             {
                 return false;
             }
         }
 
         return true;
     }

    
These methods must be provided by a derived class. They are responsible for packing and unpacking an object's state to/from a state buffer. StateManager calls them at appropriate times during the lifetime of the object, and may then pass the buffer to a persistent object store for saving.

Returns:
true on success, false otherwise.
 
 
     public synchronized boolean restore_state (InputObjectState osint ot)
     {
         if (ot == .)
         {
             try
             {
                 unpackHeader(osnew Header());
             }
             catch (IOException e)
             {
                 return false;
             }
         }
 
         return true;
     }

    
This operation activates an object. Activation of an object may entail loading its passive state from the object store and unpacking it into the memory resident form, or it may simply be a no-op. Full activation is only necessary if the object is currently marked as being PASSIVE (that is, the object was constructed as being of type ANDPERSISTENT with an existing uid and has not already been activated). Objects that are not of type ANDPERSISTENT or are persistent but have not yet been saved in an object store (so-called new persistent objects) are unaffected by this function. Returns false if PASSIVE object cannot be loaded from object store, true otherwise. The root of the object store is taken as null.

Returns:
true on success, false otherwise.
See also:
com.arjuna.ats.arjuna.objectstore.ObjectStore
 
 
     public boolean activate ()
     {
         return activate(null);
     }

    
This operation activates an object. Activation of an object may entail loading its passive state from the object store and unpacking it into the memory resident form, or it may simply be a no-op. Full activation is only necessary if the object is currently marked as being PASSIVE (that is, the object was constructed as being of type ANDPERSISTENT with an existing uid and has not already been activated). Objects that are not of type ANDPERSISTENT or are persistent but have not yet been saved in an object store (so-called new persistent objects) are unaffected by this function. Returns false if PASSIVE object cannot be loaded from object store, true otherwise.

Returns:
true on success, false otherwise.
See also:
com.arjuna.ats.arjuna.objectstore.ObjectStore
 
 
     public synchronized boolean activate (String rootName)
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::activate( "
                     + ((rootName != null) ? rootName : "null")
                     + ") for object-id " + );
         }
 
         if ( == .)
         {
             return true;
         }
 
         if ( == .)
             return false;
 
         BasicAction action = null;
         int oldStatus = ;
         boolean result = true/* assume 'succeeds' */
         boolean forceAR = false;
 
         /*
          * Check if this action has logged its presence before. If not we force
          * creation of an ActivationRecord so that each thread/action tree has
          * an ActivationRecord in it. This allows us to passivate the object
          * when the last thread has finished with it, i.e., when the last
          * ActivationRecord is gone.
          */
 
         action = BasicAction.Current();
 
         if ((action != null) && (action.status() == .))
         {
             /*
              * Only check for top-level action. This is sufficient because
              * activation records are propagated to the parent on nested
              * transaction commit, and dropped when the (nested) action aborts.
              * Thus, an object remains active as long as a single
              * ActivationRecord is being used, and we don't need to create a new
              * record for each transaction in the same hierarchy. Once
              * activated, the object remains active until the action commits or
              * aborts (at which time it may be passivated, and then reactivated
              * later by the creation of a new ActivationRecord.)
              */
 
             synchronized ()
             {
                 if (.get(action.get_uid()) == null)
                 {
                     /*
                      * May cause us to add parent as well as child.
                      */
                     
                     .put(action.get_uid(), action);
                     forceAR = true;
                 }
             }
         }
 
         if (forceAR || ( == .)
                 || ( == .))
         {
             /*
              * If object is recoverable only, then no need to set up the object
              * store.
              */
 
             if (loadObjectState())
             {
                 setupStore(rootName);
             }
             
             /* Only really activate if object is PASSIVE */
 
             if ( == .)
             {
                 /*
                  * If the object is shared between different processes, then we
                  * must load the state each time a top-level action accesses it.
                  * Otherwise we can continue to use the last state as in
                  * Dharma/ArjunaII.
                  */
 
                 if (loadObjectState())
                 {
                     InputObjectState oldState = null;
 
                     try
                     {
                         oldState = 
                                 .read_committed(type());
                     }
                     catch (ObjectStoreException e)
                     {
                         e.printStackTrace();
                         
                         oldState = null;
                     }
 
                     if (oldState != null)
                     {
                         if ((result = restore_state(oldState,
                                 .)))
                         {
                              = .;
                         }
 
                         oldState = null;
                     }
                     else {
                         ..warn_StateManager_2(type());
 
                         return false;
                     }
                 }
                 else
                 {
                     if ( == .)
                          = .;
                     else
                          = .;
                 }
             }
             else
             {
                 if ( == .)
                      = .;
                 else
                      = .;
             }
 
             /*
              * Create ActivationRecord if status changed Passive->Active or if
              * object is a new persistent object.
              */
 
             if (forceAR
                     || (( == .) || ( == .))
                     && (action != null))
             {
                 int arStatus = .;
                 ActivationRecord ar = new ActivationRecord(oldStatusthis,
                         action);
 
                 if ((arStatus = action.add(ar)) != .)
                 {
                     ar = null;
 
                     if (forceAR)
                     {
                         synchronized ()
                         {
                             .remove(action.get_uid());
                         }
                     }
 
                     if (arStatus == .)
                         result = false;
                 }
                 else
                 {
                     /*
                      * We never reset activated, so we can optimise state
                      * loading/unloading in the case of SINGLE object model
                      */
 
                      =  = true;
                 }
             }
             else
             {
                 if ( == .)
                      =  = true;
             }
         }
         
         return result;
     }

    
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 ()
     {
         return deactivate(null);
     }

    
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 commited now or not. It is assumed that this is being called during a transaction commit.

Returns:
true on success, false otherwise.
 
 
     public boolean deactivate (String rootName)
     {
         return deactivate(rootNametrue);
     }

    
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 commited now or not.

Returns:
true on success, false otherwise.
 
 
     public synchronized boolean deactivate (String rootNameboolean commit)
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::deactivate("
                     + ((rootName != null) ? rootName : "null") + ", "
                     + commit + ") for object-id " + );
         }
 
         boolean result = false;
 
         if (( && ( == .))
                 || loadObjectState())
         {
             setupStore(rootName);
 
             if (( == .)
                     || ( == .))
             {
                 String tn = type();
                 OutputObjectState newState = new OutputObjectState(,
                         tn);
 
                 /*
                  * Call save_state again to possibly get a persistent
                  * representation of the object.
                  */
 
                 if (save_state(newState))
                 {
                     try
                     {
                         if (commit)
                             result = .write_committed(tn,
                                     newState);
                         else
                             result = .write_uncommitted(,
                                     tnnewState);
                     }
                     catch (ObjectStoreException e) {
                         ..warn_StateManager_3(e);
 
                         result = false;
                     }
                 }
                 else {
                     ..warn_StateManager_4();
                 }
 
                 /*
                  * Not needed any more because activation record does this when
                  * all actions are forgotten. if (result) currentStatus =
                  * ObjectStatus.PASSIVE;
                  */
             }
         }
         else
         {
             result = true;
         }
 
         return result;
     }

    

Returns:
the object's current status (active, passive, ...)
 
 
     public synchronized int status ()
     {
         return ;
     }

    

Returns:
the type of the object (persistent, recoverable, ...)
 
 
     public synchronized int objectType ()
     {
         return ;
     }
 
     public int getObjectModel ()
     {
         return ;
     }
    
    

Returns:
the object's unique identifier.
 
 
     public final Uid get_uid ()
     {
         return ;
     }

    
Destroy the object (e.g., remove its state from the persistent store.) Calls to destroy for volatile objects (ones not maintained within the volatile object store) are ignored, and FALSE is returned.

Returns:
true on success, false otherwise.
 
 
     public synchronized boolean destroy ()
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::destroy for object-id "+);
         }
 
         boolean result = false;
 
         if ( != null)
         {
             BasicAction action = BasicAction.Current();
 
             if (action != null// add will fail if the status is wrong!
             {
                 DisposeRecord dr = new DisposeRecord(this);
 
                 if (action.add(dr) != .) {
                     dr = null;
 
                     ..warn_StateManager_6(action.get_uid());
                 }
                 else
                     result = true;
             }
             else
             {
                 try
                 {
                     result = .remove_committed(get_uid(), type());
 
                     /*
                      * Once destroyed, we can never use the object again.
                      */
 
                     if (result)
                         destroyed();
                 }
                 catch (Exception e) {
                     ..warn_StateManager_7(e);
 
                     result = false;
                 }
             }
         }
         else {
             /*
              * Not a persistent object!
              */
 
             ..warn_StateManager_8();
         }
 
         return result;
     }

    
The following function disables recovery for an object by setting the ObjectType to NEITHER (RECOVERABLE or ANDPERSISTENT). The value of this variable is checked in the modified operation so that no recovery information is created if myType is set to NEITHER.
 
 
     public synchronized void disable ()
     {
          = .;
     }

    
Print out information about the object.
 
 
     public void print (PrintWriter strm)
     {
         strm.println("Uid: " + );
         strm.println("Type: " + type());
     }

    
The object's type. Derived classes should override this to reflect their type structure. Typically this string is used for locating the object state in an object store, and reflects the hierarchy structure of the object.
 
 
     public String type ()
     {
         return "/StateManager";
     }

    

Returns:
the root of the object store this instance will use if it has to save the state of the object to storage.
 
 
     public final String getStoreRoot ()
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::getStoreRoot ()");
         }
 
         return ;
     }

    

Returns:
the object store this instance will used if it has to save the state of the object to storage.
 
 
     public ParticipantStore getStore ()
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::getStore ()");
         }
 
         if ( == null)
             setupStore();
 
         return ;
     }

    
Pack the necessary information for crash recovery.

Since:
JTS 2.1.
 
 
     protected void packHeader (OutputObjectState osHeader hdr)
             throws IOException
     {
         /*
          * If there is a transaction present than pack the process Uid of this
          * JVM and the tx id. Otherwise pack a null Uid.
          */
 
         Uid txId = ((hdr == null) ? null : hdr.getTxId());
         Uid processUid = ((hdr == null) ? null : hdr.getProcessId());
         
         try
         {
             // pack the marker first.
 
             os.packString(.);
 
             /*
              * Only pack something if there is a transaction. Otherwise the
              * application is driving this object manually, and all bets are
              * off!
              */
 
             if (txId != null)
             {
                 UidHelper.packInto(txIdos);
                 UidHelper.packInto(processUidos);
             }
             else
                 UidHelper.packInto(Uid.nullUid(), os);
             
             long birthDate = System.currentTimeMillis();
             
             if (..isTraceEnabled()) {
                 ..trace("StateManager.packHeader for object-id " + get_uid()
                         + " birth-date " + birthDate);
             }
             
             os.packLong(birthDate);
         }
         catch (IOException ex)
         {
             throw ex;
         }
         catch (Exception e)
         {
             IOException ioException = new IOException(e.toString());
             ioException.initCause(e);
             throw ioException;
         }
     }

    
Unpack the crash recovery state header information and return it.

Parameters:
txId the identity of the transaction that last caused the state to be written to the object store.
Since:
JTS 2.1.
 
 
     protected void unpackHeader (InputObjectState osHeader hdr)
             throws IOException
     {
         try
         {
             if (hdr == null)
                 throw new NullPointerException();
             
             Uid txId = null;
             Uid processUid = null;
             
             String myState = os.unpackString();
 
             if (myState.equals(.))
             {
                 txId = UidHelper.unpackFrom(os);
 
                 /*
                  * Is there going to be a Uid to unpack?
                  */
 
                 if (!txId.equals(Uid.nullUid()))
                     processUid = UidHelper.unpackFrom(os);
             }
             else {
                 ..warn_StateManager_9();
 
                 throw new IOException(..get_StateManager_15());
             }
             
             long birthDate = os.unpackLong();
             
             if (..isTraceEnabled()) {
                 ..trace("StateManager.unpackHeader for object-id " + get_uid()
                         + " birth-date " + birthDate);
             }
             
             hdr.setTxId(txId);
             hdr.setProcessId(processUid);
         }
         catch (IOException ex)
         {
             throw ex;
         }
         catch (final Throwable e)
         {
             IOException ioException = new IOException(e.toString());
             ioException.initCause(e);
             throw ioException;
         }
     }

    
The following function checks to see if the object is going out of scope while an action is still running.
 
 
     protected void terminate ()
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::terminate() for object-id " + get_uid());
         }
 
         cleanup(true);
     }
 
     protected final synchronized void setStatus (int s)
     {
          = s;
     }

    
Create object with specific uid. This constructor is primarily used when recreating an existing object. The object type is set to 'ANDPERSISTENT' this is equivalent to invoking persist in the object constructor.
 
 
     protected StateManager(Uid objUid)
     {
         this(objUid..);
     }
 
     protected StateManager(Uid objUidint ot)
     {
         this(objUidot.);
     }
 
     protected StateManager (Uid objUidint otint om)
     {
          = om;
 
         if (ot == .)
         {
              = null;
              = null;
         }
         else
         {
              = new Hashtable();
              = new Hashtable();
         }
 
          = false;
          = false;
          = .;
          = .;
          = ot;
          = null;
          = null;
 
          = objUid;
 
         if (..isTraceEnabled()) {
             ..trace("StateManager::StateManager( " + get_uid() + " )");
         }
     }
 
     protected StateManager()
     {
         this(.);
     }
 
     protected StateManager(int ot)
     {
         this(ot.);
     }
 
     protected StateManager (int otint om)
     {
          = om;
         
         if (ot == .)
         {
              = null;
              = null;
         }
         else
         {
              = new Hashtable();
              = new Hashtable();
         }
 
          = false;
          = false;
          = ((( == .) && (ot == .)) ? .
                 : .);
          = ;
          = ot;
          = null;
          = null;
 
          = new Uid();
 
         if (..isTraceEnabled()) {
             ..trace("StateManager::StateManager( " + ot + ", " + om + " )");
         }
     }
 
     /*
      * Protected non-virtual functions.
      */

    
The object's state is about to be modified, and StateManager should take a snapshot of the state if the object is being used within a transaction.

Returns:
true on success, false otherwise.
 
 
     protected synchronized boolean modified ()
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::modified() for object-id " + get_uid());
         }
 
         BasicAction action = BasicAction.Current();
         RecoveryRecord record = null;
 
         if (( == .)
                 || ( == .)) /*
                                                                * NEITHER => no
                                                                * recovery info
                                                                */
         {
             return true;
         }
 
         if ( == .) {
             ..warn_StateManager_10();
 
             activate();
         }
 
         /*
          * Need not have gone through active if new object.
          */
 
         if ( == .)
              = .;
 
         if (action != null)
         {
             /*
              * Check if this is the first call to modified in this action.
              * BasicList insert returns FALSE if the entry is already present.
              */
 
             synchronized ()
             {
                 if ((.size() > 0)
                         && (.get(action.get_uid()) != null))
                 {
                     return true;
                 }
                 else
                     .put(action.get_uid(), action);
             }
 
             /* If here then its a new action */
 
             OutputObjectState state = new OutputObjectState(type());
             int rStatus = .;
 
             if (save_state(state.))
             {
                 if (( == .)
                         && ( == .))
                 {
                     record = new RecoveryRecord(statethis);
                 }
                 else
                     record = new PersistenceRecord(statethis);
 
                 if ((rStatus = action.add(record)) != .)
                 {
                     synchronized ()
                     {
                         .remove(action.get_uid()); // remember
                                                                    // to
                                                                    // unregister
                                                                    // with
                                                                    // action
                     }
 
                     record = null;
 
                     return false;
                 }
             }
             else
                 return false;
         }
 
         return true;
     }

    
The persist function changes the type of the object from RECOVERABLE to ANDPERSISTENT. No changes are made unless the status of the object is ACTIVE, so it is not possible to change the type of the object if it has been modified.
 
 
     protected final synchronized void persist ()
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::persist() for object-id " + get_uid());
         }
 
         if ( == .)
         {
              = .;
              = .;
         }
     }

    
Object cleanup. Attempt sane cleanup when object is deleted. Handle perverse cases where multiple actions are still active as object dies.

Parameters:
fromTerminate indicates whether this method is being called from the terminate method, or from elsewhere.
See also:
terminate()
 
 
     protected final synchronized void cleanup (boolean fromTerminate)
     {
         if (..isTraceEnabled()) {
             ..trace("StateManager::cleanup() for object-id " + get_uid());
         }
 
         if ( == .)
             return;
 
         BasicAction action = null;
 
         synchronized ()
         {
             if (.size() > 0)
             {
                 Enumeration e = .keys();
 
                 while (e.hasMoreElements())
                 {
                     action = (BasicAction.remove(e.nextElement());
 
                     if (action != null)
                     {
                         /*
                          * Pop actions off using list. Don't check if action is
                          * running below so that cadavers can be created in
                          * commit protocol too.
                          */
                        AbstractRecord record = null;
                        int rStatus = .;
                        if (( == .)
                                || ( == .)) {
                            OutputObjectState state = null;
                            ..warn_StateManager_11(type());
                            /*
                             * If we get here via terminate its ok to do a
                             * save_state.
                             */
                            if (fromTerminate) {
                                state = new OutputObjectState(type());
                                if (!save_state(state)) {
                                    ..warn_StateManager_12();
                                    /* force action abort */
                                    action.preventCommit();
                                }
                            } else {
                                /* otherwise force action abort */
                                action.preventCommit();
                            }
                            /*
                             * This should be unnecessary - but just in case.
                             */
                            setupStore();
                            record = new CadaverRecord(statethis);
                            if ((rStatus = action.add(record)) != .)
                                record = null;
                        }
                        if (
                                && ( != .))
                        {
                            record = new CadaverActivationRecord(this);
                            if ((rStatus = action.add(record)) == .)
                            {
                                 = .;
                            }
                            else {
                                ..warn_StateManager_6(action.get_uid());
                                record = null;
                            }
                        }
                    }
                }
            }
        }
        /*
         * Here the object must be either RECOVERABLE or PERSISTENT. Whether or
         * not an action exists we still need to reset the object status to
         * avoid possible later confusion. What it gets set to is not important
         * really as long as it gets changed from ACTIVE_NEW which might cause
         * any running action to abort.
         */
        if ( == .)
        {
            if (( == .)
                    && ( == .))
            {
                 = .;
            }
            else
            {
                 = .;
            }
        }
         = false;
    }

    
Make sure the object store is set up, if required. The root of the object store is assumed to be null.
    protected final void setupStore ()
    {
        setupStore(null);
    }
    @SuppressWarnings("unchecked")
    protected synchronized void setupStore (String rootName)
    {
        setupStore(rootName, arjPropertyManager.getObjectStoreEnvironmentBean()
                .getObjectStoreType());
    }

    
Make sure the object store is set up, if required.

Parameters:
rootName indicates the root of the object store.
    @SuppressWarnings("unchecked")
    protected synchronized void setupStore (String rootName,
            String objectStoreType)
    {
        if (..isTraceEnabled()) {
            ..trace("StateManager::setupStore ( "
                    + ((rootName != null) ? rootName : "null") + " )");
        }
        if (!loadObjectState())
            return;
        /*
         * Already setup? Assume type will not change once object is created.
         */
        if ( != null)
            return;
        if (rootName == null)
            rootName = arjPropertyManager.getObjectStoreEnvironmentBean()
                    .getLocalOSRoot();
        /* Check if we have a store */
        if ( != null)
        {
            /* Attempting to reuse it ? */
            if ((rootName == null) || (rootName.compareTo("") == 0)
                    || (rootName.compareTo() == 0))
            {
                return;
            }
            /* No - destroy old store and create new */
             = null;
        }
        if (rootName == null)
        {
            rootName = "";
        }
        /* Create store now */
         = new String(rootName);
        if (( == .)
                || ( == .))
        {
            int sharedStatus = (( == .) ? .
                    : .);
             = StoreManager.setupStore(rootNamesharedStatus);
        }
        else {
            /*
             * Currently we should never get here! However, since Arjuna
             * supports a volatile (in memory) object store we will also
             * eventually, probably through a set of native methods.
             */
            ..warn_StateManager_13();
            throw new FatalError(..get_StateManager_14());
            // participantStore = new
            // ObjectStore(ArjunaNames.Implementation_ObjectStore_VolatileStore
            // (), storeRoot);
        }
    }

    
Do we need to load the object's state?

Returns:
true if the object state should be loaded, false otherwise.
    protected final boolean loadObjectState ()
    {
        boolean load = ( != .);
        /*
         * MULTIPLE object model requires loading of state every time, even if
         * we are RECOVERABLE - we use the volatile store.
         */
        if (!load)
        {
            /*
             * Must be SINGLE object model. So, is this the first time? If so,
             * load state.
             */
            if (( != .) && (!))
                load = true;
        }
        return load;
    }
    /*
     * Called ONLY by ActivationRecords!
     */

    
Remove action from list of using actions. If the action list empties reset state to PASSIVE. The second param tells why the action should be forgotten. This aids in resetting the state correctly.
    protected final synchronized boolean forgetAction (BasicAction action,
            boolean committedint recordType)
    {
        if (..isTraceEnabled()) {
            ..trace("StateManager::forgetAction("
                    + ((action != null) ? action.get_uid() : Uid
                    .nullUid()) + ")" + " for object-id "
                    + );
        }
        synchronized ()
        {
            .remove(action.get_uid());
        }
        if (recordType != .)
        {
            synchronized ()
            {
                if ( != null)
                {
                    .remove(action.get_uid());
                    if (.size() == 0)
                    {
                        if (committed)
                        {
                            if (( == .)
                                    && ( == .) || (action.typeOfAction() == .))
                            {
                                 =  = .;
                            }
                            else
                            {
                                 =  = .;
                            }
                        }
                        else
                        {
                            if ( == .)
                                 = ;
                            else
                                 =  = .;
                        }
                    }
                }
            }
        }
        return true;
    }

    
Remember that the specified transaction is using the object.
    protected final synchronized boolean