All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.datanucleus.ExecutionContextThreadedImpl Maven / Gradle / Ivy

Go to download

DataNucleus Core provides the primary components of a heterogenous Java persistence solution. It supports persistence API's being layered on top of the core functionality. Also includes the JDO API.

There is a newer version: 5.2.0-release
Show newest version
/**********************************************************************
Copyright (c) 2011 Andy Jefferson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Contributors:
   ...
**********************************************************************/
package org.datanucleus;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

import org.datanucleus.state.FetchPlanState;
import org.datanucleus.state.ObjectProvider;
import org.datanucleus.store.Extent;

/**
 * ExecutionContext to attempt to handle multi-threaded PM/EM cases.
 * Locks various methods in an attempt to prevent conflicting thread updates.
 * Note we could have just put this code in ExecutionContextImpl but better to split it out since the majority use-case is to have a non-thread-safe PM/EM.
 * Note also that having thread-safe ExecutionContext usage depends on much more than having this class, since SCO wrappers would need to coordinate
 * with such locks, as would the Transaction for the ExecutionContext.
 * TODO Evaluate all of the places we currently lock (when multithreaded) to find corner cases not caught.
 */
public class ExecutionContextThreadedImpl extends ExecutionContextImpl
{
    /**
     * @param ctx NucleusContext
     * @param owner Owner object (PM, EM)
     * @param options Any options affecting startup
     */
    public ExecutionContextThreadedImpl(PersistenceNucleusContext ctx, Object owner, Map options)
    {
        super(ctx, owner, options);
    }

    /**
     * Accessor for whether the object manager is multithreaded.
     * @return Whether to run multithreaded.
     */
    public boolean getMultithreaded()
    {
        return true;
    }

    public void processNontransactionalUpdate()
    {
        try
        {
            lock.lock();

            super.processNontransactionalUpdate();
        }
        finally
        {
            lock.unlock();
        }
    }

    public void enlistInTransaction(ObjectProvider sm)
    {
        try
        {
            lock.lock();

            super.enlistInTransaction(sm);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void evictFromTransaction(ObjectProvider sm)
    {
        try
        {
            lock.lock();

            super.evictFromTransaction(sm);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void addObjectProvider(ObjectProvider op)
    {
        try
        {
            lock.lock();

            super.addObjectProvider(op);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void removeObjectProvider(ObjectProvider op)
    {
        try
        {
            lock.lock();

            super.removeObjectProvider(op);
        }
        finally
        {
            lock.unlock();
        }
    }

    public ObjectProvider findObjectProvider(Object pc)
    {
        try
        {
            lock.lock();

            return super.findObjectProvider(pc);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void hereIsObjectProvider(ObjectProvider sm, Object pc)
    {
        try
        {
            lock.lock();

            super.hereIsObjectProvider(sm, pc);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void close()
    {
        try
        {
            lock.lock();

            super.close();
        }
        finally
        {
            lock.unlock();
        }
    }

    public void evictObject(Object obj)
    {
        try
        {
            lock.lock();

            super.evictObject(obj);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void refreshObject(Object obj)
    {
        try
        {
            lock.lock();

            super.refreshObject(obj);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void retrieveObject(Object obj, boolean fgOnly)
    {
        try
        {
            lock.lock();

            super.retrieveObject(obj, fgOnly);
        }
        finally
        {
            lock.unlock();
        }
    }

    public Object persistObject(Object obj, boolean merging)
    {
        try
        {
            lock.lock();

            return super.persistObject(obj, merging);
        }
        finally
        {
            lock.unlock();
        }
    }

    public Object[] persistObjects(Object[] objs)
    {
        try
        {
            lock.lock();

            return super.persistObjects(objs);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void deleteObject(Object obj)
    {
        try
        {
            lock.lock();

            super.deleteObject(obj);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void deleteObjects(Object[] objs)
    {
        try
        {
            lock.lock();

            super.deleteObjects(objs);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void makeObjectTransient(Object obj, FetchPlanState state)
    {
        try
        {
            lock.lock();

            super.makeObjectTransient(obj, state);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void makeObjectTransactional(Object obj)
    {
        try
        {
            lock.lock();

            super.makeObjectTransactional(obj);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void attachObject(ObjectProvider ownerOP, Object pc, boolean sco)
    {
        try
        {
            lock.lock();

            super.attachObject(ownerOP, pc, sco);
        }
        finally
        {
            lock.unlock();
        }
    }

    public Object attachObjectCopy(ObjectProvider ownerOP, Object pc, boolean sco)
    {
        try
        {
            lock.lock();

            return super.attachObjectCopy(ownerOP, pc, sco);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void detachObject(Object obj, FetchPlanState state)
    {
        try
        {
            lock.lock();

            super.detachObject(obj, state);
        }
        finally
        {
            lock.unlock();
        }
    }

    public Object detachObjectCopy(Object pc, FetchPlanState state)
    {
        try
        {
            lock.lock();

            return super.detachObjectCopy(pc, state);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void clearDirty(ObjectProvider op)
    {
        try
        {
            lock.lock();

            super.clearDirty(op);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void clearDirty()
    {
        try
        {
            lock.lock();

            super.clearDirty();
        }
        finally
        {
            lock.unlock();
        }
    }

    /**
     * Method to evict all current objects from L1 cache.
     */
    public void evictAllObjects()
    {
        assertIsOpen();

        try
        {
            lock.lock();

            synchronized (cache)
            {
                // All persistent non-transactional instances should be evicted here, but not yet supported
                ArrayList opsToEvict = new ArrayList();
                opsToEvict.addAll(cache.values());

                // Evict ObjectProviders and remove objects from cache
                // Performed in separate loop to avoid ConcurrentModificationException
                Iterator opIter = opsToEvict.iterator();
                while (opIter.hasNext())
                {
                    ObjectProvider op = opIter.next();
                    Object pc = op.getObject();
                    op.evict();

                    // Evict from L1
                    removeObjectFromLevel1Cache(getApiAdapter().getIdForObject(pc));
                }
            }
        }
        finally
        {
            lock.unlock();
        }
    }

    public void markDirty(ObjectProvider op, boolean directUpdate)
    {
        try
        {
            lock.lock();

            super.markDirty(op, directUpdate);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void flush()
    {
        try
        {
            lock.lock();

            super.flush();
        }
        finally
        {
            lock.unlock();
        }
    }

    public void flushInternal(boolean flushToDatastore)
    {
        try
        {
            lock.lock();

            super.flushInternal(flushToDatastore);
        }
        finally
        {
            lock.unlock();
        }
    }

    public void replaceObjectId(Object pc, Object oldID, Object newID)
    {
        try
        {
            lock.lock();

            super.replaceObjectId(pc, oldID, newID);
        }
        finally
        {
            lock.unlock();
        }
    }

    public Extent getExtent(Class pcClass, boolean subclasses)
    {
        try
        {
            lock.lock();

            return super.getExtent(pcClass, subclasses);
        }
        finally
        {
            lock.unlock();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy