public void purgeConglomerate(
TransactionManager xact_manager,
Transaction rawtran)
throws StandardException
{
OpenConglomerate open_for_ddl_lock = null;
HeapController heapcontroller = null;
TransactionManager nested_xact = null;
try
{
open_for_ddl_lock = new OpenHeap();
// Open table in intended exclusive mode in the top level
// transaction, this will stop any ddl from happening until
// purge of whole table is finished.
if (open_for_ddl_lock.init(
(ContainerHandle) null,
this,
this.format_ids,
this.collation_ids,
xact_manager,
rawtran,
false,
TransactionController.OPENMODE_FORUPDATE,
TransactionController.MODE_RECORD,
null,
null) == null)
{
throw StandardException.newException(
SQLState.HEAP_CONTAINER_NOT_FOUND,
new Long(id.getContainerId()));
}
// perform all the "real" work in a non-readonly nested user
// transaction, so that as work is completed on each page resources
// can be released. Must be careful as all locks obtained in nested
// transaction will conflict with parent transaction - so this call
// must be made only if parent transaction can have no conflicting
// locks on the table, otherwise the purge will fail with a self
// deadlock.
nested_xact = (TransactionManager)
xact_manager.startNestedUserTransaction(false);
// now open the table in a nested user transaction so that each
// page worth of work can be committed after it is done.
OpenConglomerate open_conglom = new OpenHeap();
if (open_conglom.init(
(ContainerHandle) null,
this,
this.format_ids,
this.collation_ids,
nested_xact,
nested_xact.getRawStoreXact(),
true,
TransactionController.OPENMODE_FORUPDATE,
TransactionController.MODE_RECORD,
nested_xact.getRawStoreXact().newLockingPolicy(
LockingPolicy.MODE_RECORD,
TransactionController.ISOLATION_REPEATABLE_READ, true),
null) == null)
{
throw StandardException.newException(
SQLState.HEAP_CONTAINER_NOT_FOUND,
new Long(id.getContainerId()).toString());
}
heapcontroller = new HeapController();
heapcontroller.init(open_conglom);
Page page = open_conglom.getContainer().getFirstPage();
boolean purgingDone = false;
while (page != null)
{
long pageno = page.getPageNumber();
purgingDone = heapcontroller.purgeCommittedDeletes(page);
if (purgingDone)
{
page = null;
// commit xact to free resouurces ASAP, commit will
// unlatch the page if it has not already been unlatched
// by a remove.
open_conglom.getXactMgr().commitNoSync(
TransactionController.RELEASE_LOCKS);
// the commit closes the underlying container, so let
// the heapcontroller know this has happened. Usually
// the transaction takes care of this, but this controller
// is internal, so the transaction does not know about it.
heapcontroller.closeForEndTransaction(false);
// the commit will close the underlying
open_conglom.reopen();
}
else
{
page.unlatch();
page = null;
}
page = open_conglom.getContainer().getNextPage(pageno);
}
}
finally
{
if (open_for_ddl_lock != null)