Search in sources :

Example 1 with HeapController

use of org.apache.derby.impl.store.access.heap.HeapController in project derby by apache.

the class B2IRowLocking3 method lockRowOnPage.

/**
 * Lock a btree row (row is at given slot in page).
 * <p>
 * Lock the row at the given slot in the page.  Meant to be used if caller
 * only has the slot on the page to be locked, and has not read the row
 * yet.  This routine fetches the row location field from the page, and then
 * locks that rowlocation in the base container.
 * <p>
 * Lock a btree row, enforcing the standard lock/latch protocol.
 * On return the row is locked.  Return status indicates if the lock
 * was waited for, which will mean a latch was dropped while waiting.
 * In general a false status means that the caller will either have
 * to research the tree unless some protocol has been implemented that
 * insures that the row will not have moved while the latch was dropped.
 * <p>
 * This routine request a row lock NOWAIT on the in-memory row
 * "current_row.".  If the lock is granted the routine will return true.
 * If the lock cannot be granted NOWAIT, then the routine will release
 * the latch on "current_leaf" and "aux_leaf" (if aux_leaf is non-null),
 * and then it will request a WAIT lock on the row.
 * <p>
 *
 * @param current_leaf      Latched current leaf where "current" key is.
 * @param aux_leaf          If non-null, this leaf is unlatched if the
 *                          routine has to wait on the lock.
 * @param current_slot      Slot of row to lock.
 * @param lock_fetch_desc   Descriptor for fetching just the RowLocation,
 *                          used for locking.
 * @param position          The position to lock if the lock is requested
 *                          while performing a scan, null otherwise.
 * @param lock_operation    Whether lock is for key prev to insert or not.
 * @param lock_duration     For what duration should the lock be held,
 *                          if INSTANT_DURATION, then the routine will
 *                          guarantee that lock was acquired while holding
 *                          the latch, but then immediately release the
 *                          lock.  If COMMIT_DURATION or MANUAL_DURATION
 *                          then the lock be held when routine returns
 *                          successfully.
 *
 * @exception  StandardException  Standard exception policy.
 */
private boolean lockRowOnPage(LeafControlRow current_leaf, LeafControlRow aux_leaf, int current_slot, BTreeRowPosition position, FetchDescriptor lock_fetch_desc, DataValueDescriptor[] lock_template, RowLocation lock_row_loc, int lock_operation, int lock_duration) throws StandardException {
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(current_leaf != null);
        if (current_slot <= 0 || current_slot >= current_leaf.getPage().recordCount()) {
            SanityManager.THROWASSERT("current_slot = " + current_slot + "; current_leaf.getPage().recordCount() = " + current_leaf.getPage().recordCount());
        }
        SanityManager.ASSERT(lock_template != null, "template is null");
        // For now the RowLocation is expected to be the object located in
        // the last column of the lock_template, this may change if we
        // ever support rows with RowLocations somewhere else.
        SanityManager.ASSERT(lock_row_loc == lock_template[lock_template.length - 1], "row_loc is not the object in last column of lock_template.");
        if (position != null) {
            SanityManager.ASSERT(current_leaf == position.current_leaf);
            SanityManager.ASSERT(current_slot == position.current_slot);
        }
    }
    // Fetch the row location to lock.
    RecordHandle rec_handle = current_leaf.getPage().fetchFromSlot((RecordHandle) null, current_slot, lock_template, lock_fetch_desc, true);
    // First try to get the lock NOWAIT, while latch is held.
    boolean ret_status = base_cc.lockRow(lock_row_loc, lock_operation, false, /* NOWAIT */
    lock_duration);
    if (!ret_status) {
        if (position != null) {
            // since we're releasing the lock in the middle of a scan,
            // save the current position of the scan before releasing the
            // latch
            position.saveMeAndReleasePage();
        } else if (current_leaf != null) {
            // otherwise, just release the latch
            current_leaf.release();
            current_leaf = null;
        }
        if (aux_leaf != null) {
            aux_leaf.release();
            aux_leaf = null;
        }
        if ((((HeapController) base_cc).getOpenConglomerate().getOpenMode() & TransactionManager.OPENMODE_LOCK_ROW_NOWAIT) != 0) {
            throw StandardException.newException(SQLState.LOCK_TIMEOUT);
        }
        base_cc.lockRow(lock_row_loc, lock_operation, true, /* WAIT */
        lock_duration);
    }
    return (ret_status);
}
Also used : HeapController(org.apache.derby.impl.store.access.heap.HeapController) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle)

Aggregations

RecordHandle (org.apache.derby.iapi.store.raw.RecordHandle)1 HeapController (org.apache.derby.impl.store.access.heap.HeapController)1