use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.
the class BTreeController method start_xact_and_dosplit.
/**
* Start an internal transaction and do the split.
* <p>
* This routine starts a new transaction, and handles any errors that
* may come during the transaction. This transation must not obtain any
* locks as they are likely to conflict with the current user transaction.
* <p>
* If attempt_to_reclaim_deleted_rows is true this routine will
* attempt to reclaim space on the leaf page input, by purging
* committed deleted rows from the leaf. If it succeeds in purging at
* least one row, then it will commit the internal transaction and return
* without actually performing a split.
*
* @param scratch_template A scratch template used to search a page.
* @param rowToInsert The row to insert, make sure during split to
* make room for this row.
*
* @exception StandardException Standard exception policy.
*/
private long start_xact_and_dosplit(boolean attempt_to_reclaim_deleted_rows, long leaf_pageno, DataValueDescriptor[] scratch_template, DataValueDescriptor[] rowToInsert, int flag) throws StandardException {
TransactionManager split_xact = null;
OpenBTree split_open_btree = null;
ControlRow root = null;
// Get an internal transaction to be used for the split.
split_xact = this.init_open_user_scans.getInternalTransaction();
if (SanityManager.DEBUG) {
if (((getOpenMode() & ContainerHandle.MODE_FORUPDATE) != ContainerHandle.MODE_FORUPDATE)) {
SanityManager.THROWASSERT("Container not opened with update should not cause split");
}
}
boolean do_split = true;
if (attempt_to_reclaim_deleted_rows) {
// Get lock on base table.
ConglomerateController base_cc = null;
try {
base_cc = this.getConglomerate().lockTable(split_xact, (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_LOCK_NOWAIT), TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
} catch (StandardException se) {
// any error just don't try to reclaim deleted rows. The
// expected error is that we can't get the lock, which the
// current interface throws as a containerNotFound exception.
}
if (base_cc != null) {
// we got IX lock on the base table, so can try reclaim space.
// We can only reclaim space by opening the btree in row lock
// mode. Table level lock row recovery is hard as we can't
// determine if the deleted rows we encounter have been
// deleted by our parent caller and have been committed or
// not. We will have to get those rows offline.
split_open_btree = new OpenBTree();
split_open_btree.init(this.init_open_user_scans, split_xact, // open the container.
null, split_xact.getRawStoreXact(), false, (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_LOCK_NOWAIT), TransactionManager.MODE_RECORD, this.getConglomerate().getBtreeLockingPolicy(split_xact.getRawStoreXact(), TransactionController.MODE_RECORD, LockingPolicy.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, (ConglomerateController) base_cc, split_open_btree), this.getConglomerate(), (LogicalUndo) null, (DynamicCompiledOpenConglomInfo) null);
// don't split if we reclaim any rows.
do_split = !reclaim_deleted_rows(split_open_btree, leaf_pageno);
// on return if !do_split then the latch on leaf_pageno is held
// and will be released by the committing or aborting the
// transaction. If a purge has been done, no other action on
// the page should be attempted (ie. a split) before committing
// the purges.
split_open_btree.close();
}
}
long new_leaf_pageno = leaf_pageno;
if (do_split) {
// no space was reclaimed from deleted rows, so do split to allow
// space for a subsequent insert.
split_open_btree = new OpenBTree();
split_open_btree.init(this.init_open_user_scans, split_xact, // open the container.
null, split_xact.getRawStoreXact(), false, // use same mode this controller
getOpenMode(), // was opened with
TransactionManager.MODE_NONE, this.getConglomerate().getBtreeLockingPolicy(split_xact.getRawStoreXact(), this.init_lock_level, LockingPolicy.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // no base row locks during split
(ConglomerateController) null, split_open_btree), this.getConglomerate(), (LogicalUndo) null, (DynamicCompiledOpenConglomInfo) null);
// Get the root page back, and perform a split following the
// to-be-inserted key. The split releases the root page latch.
root = ControlRow.get(split_open_btree, BTree.ROOTPAGEID);
if (SanityManager.DEBUG)
SanityManager.ASSERT(root.page.isLatched());
new_leaf_pageno = root.splitFor(split_open_btree, scratch_template, null, rowToInsert, flag);
split_open_btree.close();
}
split_xact.commit();
split_xact.destroy();
return (new_leaf_pageno);
}
use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.
the class CacheLock method saveProperty.
void saveProperty(TransactionController tc, String key, Serializable value) throws StandardException {
if (saveServiceProperty(key, value))
return;
// Do a scan to see if the property already exists in the Conglomerate.
ScanController scan = this.openScan(tc, key, TransactionController.OPENMODE_FORUPDATE);
DataValueDescriptor[] row = makeNewTemplate();
if (scan.fetchNext(row)) {
if (value == null) {
// A null input value means that we should delete the row
scan.delete();
} else {
// a value already exists, just replace the second columm
row[1] = new UserType(value);
scan.replace(row, (FormatableBitSet) null);
}
scan.close();
} else {
// The value does not exist in the Conglomerate.
scan.close();
scan = null;
if (value != null) {
// not a delete request, so insert the new property.
row = makeNewTemplate(key, value);
ConglomerateController cc = tc.openConglomerate(propertiesConglomId, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
cc.insert(row);
cc.close();
}
}
}
use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.
the class B2I method lockTable.
/**
* Lock the base table.
* <p>
* Assumes that segment of the base container is the same as the segment
* of the btree segment.
* <p>
* RESOLVE - we really want to get the lock without opening the container.
* raw store will be providing this.
*
* @param xact_manager Transaction to associate the lock with.
*
* @exception StandardException Standard exception policy.
*/
public final ConglomerateController lockTable(TransactionManager xact_manager, int open_mode, int lock_level, int isolation_level) throws StandardException {
open_mode |= TransactionController.OPENMODE_FOR_LOCK_ONLY;
// open the base conglomerate - just to get the table lock.
ConglomerateController cc = xact_manager.openConglomerate(this.baseConglomerateId, false, open_mode, lock_level, isolation_level);
return (cc);
}
Aggregations