Package com.sleepycat.je.txn

Source Code of com.sleepycat.je.txn.LockerFactory

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002, 2011 Oracle and/or its affiliates.  All rights reserved.
*
*/

package com.sleepycat.je.txn;

import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.DbInternal;
import com.sleepycat.je.Environment;
import com.sleepycat.je.Transaction;
import com.sleepycat.je.TransactionConfig;
import com.sleepycat.je.dbi.DatabaseImpl;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.log.ReplicationContext;

/**
* Factory of static methods for creating Locker objects.
*/
public class LockerFactory {

    /**
     * Get a locker for a write operation, checking whether the db and
     * environment is transactional or not. Must return a non null locker.
     */
    public static Locker getWritableLocker(Environment env,
                                           Transaction userTxn,
                                           boolean isInternalDb,
                                           boolean dbIsTransactional,
                                           boolean autoTxnIsReplicated)
        throws DatabaseException {

        return getWritableLocker
            (env, userTxn, isInternalDb, dbIsTransactional,
             autoTxnIsReplicated, null /*autoCommitConfig*/);
    }

    /**
     * Get a locker for a write operation.
     *
     * @param autoTxnIsReplicated is true if this transaction is
     * executed on a rep group master, and needs to be broadcast.
     * Currently, all application-created transactions are of the type
     * com.sleepycat.je.txn.Txn, and are replicated if the parent
     * environment is replicated. Auto Txns are trickier because they may
     * be created for a local write operation, such as log cleaning.
     *
     * @throws IllegalArgumentException via db/cursor read/write methods.
     */
    public static Locker getWritableLocker(Environment env,
                                           Transaction userTxn,
                                           boolean isInternalDb,
                                           boolean dbIsTransactional,
                                           boolean autoTxnIsReplicated,
                                           TransactionConfig autoCommitConfig)
        throws DatabaseException {

        EnvironmentImpl envImpl = DbInternal.getEnvironmentImpl(env);
        boolean envIsTransactional = envImpl.isTransactional();

        if (userTxn == null) {
            Transaction xaLocker = env.getThreadTransaction();
            if (xaLocker != null) {
                return DbInternal.getLocker(xaLocker);
            }
        }

        if (dbIsTransactional && userTxn == null) {

            if (autoCommitConfig == null) {
                autoCommitConfig = DbInternal.getDefaultTxnConfig(env);
            }

            return Txn.createAutoTxn(envImpl,
                                     autoCommitConfig,
                                     (autoTxnIsReplicated ?
                                      ReplicationContext.MASTER :
                                      ReplicationContext.NO_REPLICATE));

        } else if (userTxn == null) {
            /* Non-transactional user operations use ThreadLocker. */
            return ThreadLocker.createThreadLocker(envImpl);
        } else {

            /*
             * The user provided a transaction, the environment and the
             * database had better be opened transactionally.
             */
            if (!isInternalDb && !envIsTransactional) {
                throw new IllegalArgumentException
                    ("A Transaction cannot be used because the"+
                     " environment was opened non-transactionally");
            }
            if (!dbIsTransactional) {
                throw new IllegalArgumentException
                    ("A Transaction cannot be used because the" +
                     " database was opened non-transactionally");
            }

            /*
             * Use the locker for the given transaction.  For read-comitted,
             * wrap the given transactional locker in a special locker for that
             * isolation level.
             */
            Locker locker = DbInternal.getLocker(userTxn);
            if (locker.isReadCommittedIsolation()) {
                return ReadCommittedLocker.
                    createReadCommittedLocker(envImpl, locker);
            }
           
            return locker;
        }
    }

    /**
     * Get a locker for a read or cursor operation.
     *
     * @throws IllegalArgumentException via db/cursor read/write methods.
     */
    public static Locker getReadableLocker(Environment env,
                                           Transaction userTxn,
                                           boolean dbIsTransactional,
                                           boolean readCommittedIsolation)
        throws DatabaseException {

        if (userTxn != null && !dbIsTransactional) {
            throw new IllegalArgumentException
                ("A Transaction cannot be used because the" +
                 " database was opened non-transactionally");
        }

        Locker locker = null;
        if (userTxn != null) {

            /*
             * Use the locker for the given transaction.  Request read-comitted
             * if that isolation level is configured for the transaction, or if
             * true is passed for the parameter (this is the case when
             * read-committed is configured for the cursor).
             */
            locker = DbInternal.getLocker(userTxn);
            if (locker.isReadCommittedIsolation()) {
                readCommittedIsolation = true;
            }
        }

        return getReadableLocker(env, locker, readCommittedIsolation);
    }

    /**
     * Get a locker for this database handle for a read or cursor operation.
     *
     * @throws IllegalArgumentException via db/cursor read/write methods.
     */
    public static Locker getReadableLocker(Environment env,
                                           Database dbHandle,
                                           Locker locker,
                                           boolean readCommittedIsolation)
        throws DatabaseException {

        DatabaseImpl dbImpl = DbInternal.getDatabaseImpl(dbHandle);
        if (!dbImpl.isTransactional() &&
            locker != null &&
            locker.isTransactional()) {
            throw new IllegalArgumentException
                ("A Transaction cannot be used because the" +
                 " database was opened non-transactionally");
        }

        /* Don't reuse a non-transactional locker. */
        if (locker != null && !locker.isTransactional()) {
            locker = null;
        }

        /*
         * Request read-comitted if that isolation level is configured for the
         * locker being reused, or if true is passed for the parameter (this is
         * the case when read-committed is configured for the cursor).
         */
        if (locker != null && locker.isReadCommittedIsolation()) {
            readCommittedIsolation = true;
        }

        return getReadableLocker(env, locker, readCommittedIsolation);
    }

    /**
     * Get a non-transactional locker for internal database operations.  Always
     * non replicated.
     *
     * This method is not called for user txns and should not throw a Java
     * runtime exception (IllegalArgument, etc).
     */
    public static
        Locker getInternalReadOperationLocker(EnvironmentImpl envImpl) {

        return BasicLocker.createBasicLocker(envImpl);
    }

    /**
     * Get a locker for a read or cursor operation.
     */
    private static Locker getReadableLocker(Environment env,
                                            Locker locker,
                                            boolean readCommittedIsolation)
        throws DatabaseException {

        EnvironmentImpl envImpl = DbInternal.getEnvironmentImpl(env);

        if (locker == null) {
            Transaction xaTxn = env.getThreadTransaction();
            if (xaTxn != null) {
                return DbInternal.getLocker(xaTxn);
            }
        }

        if (locker == null) {
            /* Non-transactional user operations use ThreadLocker. */
            locker = ThreadLocker.createThreadLocker(envImpl);
        } else {

            /*
             * Use the given locker.  For read-committed, wrap the given
             * transactional locker in a special locker for that isolation
             * level.
             */
            if (readCommittedIsolation) {
                locker = ReadCommittedLocker.
                    createReadCommittedLocker(envImpl, locker);
            }
        }
        return locker;
    }
}
TOP

Related Classes of com.sleepycat.je.txn.LockerFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.