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

com.sleepycat.je.txn.BuddyLocker Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.txn;

import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.OperationFailureException;
import com.sleepycat.je.Transaction;
import com.sleepycat.je.dbi.EnvironmentImpl;

/**
 * Extends BasicLocker to share locks with another specific locker.
 *
 * 

In general, a BuddyLocker can be used whenever the primary (API) locker * is in use, and we need to lock a node and release that lock before the * primary locker transaction ends. In other words, for this particular lock * we don't want to use two-phase locking. To accomplish that we use a * separate BuddyLocker instance to hold the lock, while sharing locks with the * primary locker. The BuddyLocker can be closed to release this particular * lock, without releasing the other locks held by the primary locker.

* *

In particular, a ReadCommittedLocker extends BuddyLocker. The * ReadCommittedLocker keeps track of read locks, while its buddy Txn keeps * track of write locks. The two lockers must share locks to prevent * conflicts.

* *

In addition, a BuddyLocker is used when acquiring a RANGE_INSERT lock. * RANGE_INSERT only needs to be held until the point we have inserted the new * node into the BIN. A separate locker is therefore used so we can release * that lock separately when the insertion into the BIN is complete. But the * RANGE_INSERT lock must not conflict with locks held by the primary locker. * So a BuddyLocker is used that shares locks with the primary locker.

*/ public class BuddyLocker extends BasicLocker { private final Locker buddy; /** * Creates a BuddyLocker. */ protected BuddyLocker(EnvironmentImpl env, Locker buddy) { super(env, buddy.getDefaultNoWait()); this.buddy = buddy; buddy.addBuddy(this); } public static BuddyLocker createBuddyLocker(EnvironmentImpl env, Locker buddy) throws DatabaseException { return new BuddyLocker(env, buddy); } @Override void close() { super.close(); buddy.removeBuddy(this); } /** * Returns the buddy locker. */ @Override Locker getBuddy() { return buddy; } /** * Forwards this call to the buddy locker. This object itself is never * transactional but the buddy may be. */ @Override public Txn getTxnLocker() { return buddy.getTxnLocker(); } /** * Forwards this call to the buddy locker. This object itself is never * transactional but the buddy may be. */ @Override public Transaction getTransaction() { return buddy.getTransaction(); } /** * Forwards this call to the base class and to the buddy locker. */ @Override public void releaseNonTxnLocks() throws DatabaseException { super.releaseNonTxnLocks(); buddy.releaseNonTxnLocks(); } /** * Returns whether this locker can share locks with the given locker. */ @Override public boolean sharesLocksWith(Locker other) { if (super.sharesLocksWith(other)) { return true; } else { return (buddy == other || other.getBuddy() == this || buddy == other.getBuddy()); } } /** * Returns the lock timeout of the buddy locker, since this locker has no * independent timeout. */ @Override public long getLockTimeout() { return buddy.getLockTimeout(); } /** * Returns the transaction timeout of the buddy locker, since this locker * has no independent timeout. */ @Override public long getTxnTimeout() { return buddy.getTxnTimeout(); } /** * Sets the lock timeout of the buddy locker, since this locker has no * independent timeout. */ @Override public void setLockTimeout(long timeout) { buddy.setLockTimeout(timeout); } /** * Sets the transaction timeout of the buddy locker, since this locker has * no independent timeout. */ @Override public void setTxnTimeout(long timeout) { buddy.setTxnTimeout(timeout); } /** * Returns whether the buddy locker is timed out, since this locker has no * independent timeout. */ @Override public boolean isTimedOut() { return buddy.isTimedOut(); } /** * Returns the buddy locker's start time, since this locker has no * independent timeout. */ @Override public long getTxnStartMillis() { return buddy.getTxnStartMillis(); } /** * Forwards to the buddy locker, since the buddy may be transactional. */ @Override public void setOnlyAbortable(OperationFailureException cause) { buddy.setOnlyAbortable(cause); } /** * Forwards to the parent buddy locker, so the buddy can check itself and * all of its child buddies. */ @Override public void checkPreempted(final Locker allowPreemptedLocker) throws OperationFailureException { buddy.checkPreempted(allowPreemptedLocker); } /** * Consider this locker replicated if its buddy (Txn) is replicated. */ @Override public boolean isReplicated() { return buddy.isReplicated(); } /** * Consider this locker local-write if its buddy is local-write. */ @Override public boolean isLocalWrite() { return buddy.isLocalWrite(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy