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);
}
Aggregations