Called just before the list itself is deleted.

@param transaction causing the deleteion of the list.
@throws ObjectManagerException
761610
public synchronized void preDelete(Transaction transaction)
                    throws ObjectManagerException
    {
        final String methodName = "preDelete";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, new Object[] { transaction });

        // TODO Remove this fix, we should not need it now we do not split checkpoint sets.
        // Defect 326031
        // We only need to do this check once so at recovery time we
        // can rely on it having been done when the transaction first 
        // ran.
        // TODO: Can we avoid this check by grouping transaction work into a single checkpoint?
        // TODO: Re tested this on 18/6/07 and the failure still occurs even though we now write
        // TODO: complete transactions in a checkpoint. Here is a scenarion that might cause this,
        // TODO: however the actual test ( performance) does the delete for the entry and list as two
        //       separate serial tracactions!
        // 
        //   Application Thread          Checkpoint Helper      LogRecords   
        //  
        //   Delete Entry                                       Delete Entry 
        //   Delete List                                        Delete List
        //                               SetRequiresCheckpoint
        // 
        //                               Checkpoint Start       Checkpoint Start. 
        //                                                      Checkpoint Entry(Deleted)
        //                                                      Checkpoint List(Deleted)
        //
        //   Commit                                             Commit
        //   Delete Entry/List from Store
        //                               Flush ObjectStore             
        //                               Checkpoint End         Checkpoint End.  
        // 
        //   
        //   Crash 
        // 
        //   Recover List in Deleted state, 
        //   Entry not yet recovered in deleted state.

        if (transaction.getObjectManagerStateState() != ObjectManagerState.stateReplayingLog) {
            // The list must be empty, apart from links this transaction will delete.
            Token nextToken = head;
            while (nextToken != null) {
                Link nextLink = (Link) nextToken.getManagedObject();
                if (nextLink.willBeDeleted(transaction))
                    nextToken = nextLink.next;
                else {
                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this, cclass,
                                   methodName,
                                   "via CollentionNotEmptyException"
                                                   + "size=" + size + "(long)"
                                                   + " nextLink.state=" + nextLink.state + "(int) " + Link.stateNames[nextLink.state]
                                                   + "\n nextLink.getTransactionLock()=" + nextLink.getTransactionLock() + "(transactionLock)"
                                        );

                    throw new CollectionNotEmptyException(this, size, transaction);
                    //System.out.println("LinkedList.preDelete nextLink.state ="+nextLink.state+" "+Link.stateNames[nextLink.state]
                    //                  +"\n nextLink.getTransactionLock()="+nextLink.getTransactionLock() 
                    //                  );
                    //break;
                } // if (  nextLink.state == Link.stateToBeDeleted...
            } // while (nextToken != null).
        } // if not recovering...

        super.preDelete(transaction); // Also takes a lock.
        // Visibility is now restricted to our transaction only.

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    }
899204
public void delete(Object entity) {
    try {
      entityManager.executeEntityListeners(CallbackType.PRE_DELETE, entity);
      Key nativeKey = Marshaller.marshalKey(entityManager, entity);
      nativeWriter.delete(nativeKey);
      entityManager.executeEntityListeners(CallbackType.POST_DELETE, entity);
    } catch (DatastoreException exp) {
      throw DatastoreUtils.wrap(exp);
    }
  }
551949
void deleteAll() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                sessionFactory.getCurrentSession().createQuery("DELETE FROM VersionInfo").executeUpdate();
            }
        });
    }
1253266
public void deleteSeen(SITransaction transaction)
      throws SISessionUnavailableException, SISessionDroppedException,
             SIConnectionUnavailableException, SIConnectionDroppedException,
             SIResourceException, SIConnectionLostException, SILimitExceededException,
             SIIncorrectCallException, SIMessageNotLockedException, 
             SIErrorException
   {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc,"deleteSeen", transaction);
      
      synchronized(lmeOperationMonitor)
      {
         
         checkValid();
               
         // If we have seen any messages....
         int numSeenMsgs = getSeenMessageCount();
         
         if (numSeenMsgs > 0)
         {
            // Start d181719
            JsMessage[] seenRecoverableMessages = new JsMessage[numSeenMsgs];
            int numOfMessagesNeedingDeleting = 0;
            
            // Go through each seen message
            for (int i=0; i < nextIndex; ++i)
            {
               if (messages[i] != null)
               {
                  // Only add the message to the list of messages to delete if it is recoverable
                  if (CommsUtils.isRecoverable(messages[i], consumerSession.getUnrecoverableReliability()))                               // f177889
                  {                                                                 // f177889
                     seenRecoverableMessages[numOfMessagesNeedingDeleting] = messages[i];         // f177889
                     ++numOfMessagesNeedingDeleting;
                  }                                                                 // f177889
                  
                  // Delete it from the main pile
                  messages[i] = null;
               }
            }
            
            if (numOfMessagesNeedingDeleting > 0)
            {
               if (transaction != null)
               {
                  synchronized (transaction)
                  {
                     // Check transaction is in a valid state.
                     // Enlisted for an XA UOW and not rolledback or
                     // completed for a local transaction.
                     if (!((Transaction) transaction).isValid())
                     {
                        throw new SIIncorrectCallException(
                           nls.getFormattedMessage("TRANSACTION_COMPLETE_SICO1022", null, null)
                        );
                     }
                     
                     deleteMessages(seenRecoverableMessages, transaction);
                  }
               }
               else
               {
                  deleteMessages(seenRecoverableMessages, null);
               }
            }
            // End d181719
         }
         // End f191114
      }
      
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc,"deleteSeen");
   }
766192
public Token removeFirst(Transaction transaction)
                    throws ObjectManagerException {
        final String methodName = "removeFirst";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, new Object[] { transaction });

        Link first;
        Token tokenToReturn;
        // Prevent a clash with a backing out transaction.
        synchronized (transaction.internalTransaction) {
            //TODO Having locked on the Internal transaction we should check that this still refers back to the
            //TODO callers external transaction.
            synchronized (this) {
                first = nextLink(null,
                                 transaction,
                                 getTransactionUnlockSequence());
                if (first == null) { // Is there a first element?
                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this, cclass, methodName, "via java.util.NoSuchElementException");
                    throw new java.util.NoSuchElementException();
                } // (first == null).

                // Assign the tokenToReturn while we have the list locked so that the ObjectManager 
                // cannot backout this transaction and remove the link under another transaction 
                // causing this thread to see a null Token as a return value.
                tokenToReturn = first.data;

                first.requestDelete(transaction); // Mark for deletion. 

                // If the link is available to all adjust list visible length available.
                // In the case where we delete a link added by the same transaction we have no incremented 
                // the available size yet because we have not yet committed so we would not decrement it.
                if (!first.isLocked())
                    decrementAvailableSize();
            } // synchronized (this).

            // We can release the synchronize lock on the list because we don't care if the
            // link which we are going to delete is changed before we write the log record.
            // Log what we intend to do. Reserve enough spare log space so that the eventual
            // optimistic replace that removes the link from the list is certain to succeed
            // in being written as well. 

            try {
                transaction.delete(first,
                                   logSpaceForDelete());
            } catch (LogFileFullException exception) {
                // No FFDC Code Needed, transaction.delete() has already done this.
                unRemove(first);
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this, cclass, methodName, exception);
                throw exception;

                // We should not see ObjectStoreFullException because the ObjectStore already 
                // holds sufficient space to guarantee deletes work.
//      } catch (ObjectStoreFullException exception) {
//        // No FFDC Code Needed, transaction.delete() has already done this.
//        unRemove(first);
//        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
//        trace.exit(this, cclass, methodName, exception);
//        throw exception;

            } catch (InvalidStateException exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    methodName,
                                                    exception,
                                                    "1:698:1.40");
                unRemove(first);
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this, cclass, methodName, exception);
                throw exception;
            } // catch (LogFileFullException exception).
        } // synchronized (transaction.internalTransaction).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName, new Object[] { tokenToReturn });
        return tokenToReturn;
    }
389102
protected void recoveryCompleted(Transaction transaction)
                    throws ObjectManagerException
    {
        throw new InvalidStateException(this, InternalTransaction.stateTerminated, InternalTransaction.stateNames[InternalTransaction.stateTerminated]);
    }
560150
private final void complete(boolean reUse,
                                Transaction transaction)
                    throws ObjectManagerException {
        final String methodName = "complete";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, new Object[] { new Boolean(reUse),
                                                                transaction });

        // No longer any need to include this transaction in a Checkpoint.
        requiresPersistentCheckpoint = false;
        // Clear any remaining state.
        logicalUnitOfWork.XID = null;
        transactionLock = new TransactionLock(this);
        includedManagedObjects.clear();
        callbackTokens.clear();
        allPersistentTokensToNotify.clear();
        loggedSerializedBytes.clear();
        logSequenceNumbers.clear();
        managedObjectSequenceNumbers.clear();
        useCount++;

        if (reUse) { // Reset the transaction for further use.
            // Note that we do not clear the transactionReference because the caller is still holding it.
            // If the caller releases his reference then the reference will be found by ObjectManagerState
            // and this InternalTransaction may be reused for another external Transaction.

        } else { // Do not chain.
            // Make sure the external Transaction cannot reach this internal one.
            transaction.internalTransaction = objectManagerState.dummyInternalTransaction;
            // This may not be sufficient to prevent its being used if the external Transaction already has passed
            // the point where it has picked up the referenece to the Internaltransaction. Hence we terminate the
            // InternalTransaction if it is preemptively backed out. See ObjectManagerstate.performCheckpoint()
            // where transactions are backed out without holding the internal transaction synchronize lock.
            if (transactionReference != null)
                transactionReference.clear(); // Inhibt an enqueue of the transactionReference.
            // If a reference is enqueued we are already in inactive state for this
            // transactionReferenceSequence so no action will occur.

            // Tell the ObjectManager that we no longer exist as an active transaction.
            objectManagerState.deRegisterTransaction(this);

        } // if (reUse).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    }
305264
public long size(Transaction transaction)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass,
                        "size",
                        "Transaction=" + transaction);

        long totalSize = 0; // Size to return.
        for (int i = 0; i < subLists.length; i++) {
            totalSize = totalSize + subLists[i].size(transaction);
        } // for subLists.

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass,
                       "size",
                       "return=" + totalSize);
        return totalSize;
    }
1258054
final public void delete() {
		Transaction t = new Transaction();
		try {
			delete(t);
			t.setSuccessful(true);
		} finally {
			t.finish();
		}
	}
1235606
public void rollbackSetRollbackOnly(List objects)
    {
        log.info("rollbackSetRollbackOnly method was called");
        storeObjects(objects);
        /*
        setRollbackOnly does only rollback the transaction, the client will not be
        notified by an RemoteException (tested on JBoss)
        */
        getSessionContext().setRollbackOnly();
        /*
        seems that some appServer expect that all used resources will be closed before
        the JTA-TXManager does call Synchronization#beforeCompletion(), so we have
        to cleanup used resources. This could be done by call abort on odmg-api
        */
        getImplementation().currentTransaction().abort();
    }
1133022
@SuppressWarnings({"OverlyLongMethod"})
    public void clearProperties(@NotNull final PersistentStoreTransaction txn, @NotNull final Entity entity) {
        final Transaction envTxn = txn.getEnvironmentTransaction();
        final PersistentEntityId id = (PersistentEntityId) entity.getId();
        final int entityTypeId = id.getTypeId();
        final long entityLocalId = id.getLocalId();
        final PropertiesTable properties = getPropertiesTable(txn, entityTypeId);
        final PropertyKey propertyKey = new PropertyKey(entityLocalId, 0);
        try (Cursor cursor = getPrimaryPropertyIndexCursor(txn, properties)) {
            for (boolean success = cursor.getSearchKeyRange(PropertyKey.propertyKeyToEntry(propertyKey)) != null;
                 success; success = cursor.getNext()) {
                ByteIterable keyEntry = cursor.getKey();
                final PropertyKey key = PropertyKey.entryToPropertyKey(keyEntry);
                if (key.getEntityLocalId() != entityLocalId) {
                    break;
                }
                final int propertyId = key.getPropertyId();
                final ByteIterable value = cursor.getValue();
                final PropertyValue propValue = propertyTypes.entryToPropertyValue(value);
                txn.propertyChanged(id, propertyId, propValue.getData(), null);
                properties.deleteNoFail(txn, entityLocalId, value, propertyId, propValue.getType());
            }
        }
    }
1261753
void postBackout(Transaction transaction)
                    throws ObjectManagerException
    {
        throw new InvalidStateException(this, InternalTransaction.stateTerminated, InternalTransaction.stateNames[InternalTransaction.stateTerminated]);
    }
830760
void postCommit(Transaction transaction)
                    throws ObjectManagerException
    {
        throw new InvalidStateException(this, InternalTransaction.stateTerminated, InternalTransaction.stateNames[InternalTransaction.stateTerminated]);
    }
151770
public void afterCompletion(TransactionCommon transaction, boolean committed)
    {
        // When the reference count is about to reach zero, this class registers *itself* as
        // a transaction callback. This method then gets called after the transaction
        // completes and the item's itemReferencesDroppedToZero callback is called.
        if (isAvailable())
        {
        	try
        	{
        		Item item = (Item) getItem();
        		if (null != item)
        		{
        			item.itemReferencesDroppedToZero();
        		}
			} 
        	catch (SevereMessageStoreException e) 
        	{
	            FFDCFilter.processException(e, "com.ibm.ws.sib.msgstore.cache.links.ItemLink.afterCompletion", "1:286:1.104.1.1");
	            if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) SibTr.event(this, tc, "Exception caught attempting to drop item reference count to zero!", e);
			}

        }
    }
520822
public boolean isEmpty(Transaction transaction)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass,
                        "isEmpty",
                        "Transaction=" + transaction);

        boolean empty = true; // Empty status to return.
        for (int i = 0; i < subLists.length; i++) {
            if (!subLists[i].isEmpty(transaction)) {
                empty = false;
                break;
            }
        } // for subLists.

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass,
                       "size",
                       "return=" + empty);
        return empty;
    }
706038
@Override
	public void rollback() throws TransactionManagementException {
		logger.entering(CLASSNAME, "rollback");
		try {
			if (userTran.getStatus() != Status.STATUS_NO_TRANSACTION) {
				userTran.rollback();
			}
			logger.log(Level.FINE, "javax.transaction.Status: {0}", userTran.getStatus());
		} catch (IllegalStateException e) {
			throw new TransactionManagementException(e);
		} catch (SecurityException e) {
			throw new TransactionManagementException(e);
		} catch (SystemException e) {
			throw new TransactionManagementException(e);
		}
		logger.exiting(CLASSNAME, "rollback");
	}
624599
protected void doCleanupAfterCompletion(Object transaction) {
        ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) transaction;

        super.doCleanupAfterCompletion(actualTransactionObject
                .getHibernateTransactionObject());
        ldapManagerDelegate.doCleanupAfterCompletion(actualTransactionObject
                .getLdapTransactionObject());
    }