{
// requeue if work was not completed in this try because of locks
boolean requeue_work = false;
TransactionManager tc = (TransactionManager)
this.access_factory.getAndNameTransaction(
contextMgr, AccessFactoryGlobals.SYS_TRANS_NAME);
TransactionManager internal_xact = tc.getInternalTransaction();
if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON("verbose_btree_post_commit"))
System.out.println("starting internal xact\n");
}
OpenBTree open_btree = null;
try
{
// Get lock on base table.
// First attempt to get a table lock on the btree. This lock is
// requested NOWAIT to not impede normal operation on the table.
// If the lock were to wait then the current lock manager livelock
// algorithm would block all subsequent lock requests on this
// btree even if they are compatible with the current holder of
// the lock.
//
// If this lock is granted then:
// 1) deleted rows on the page can automatically be purged as
// they must be committed, otherwise lock would not have been
// granted.
// 2) if all rows from page are reclaimed then a structure shrink
// which requires table level lock can be executed.
//
open_btree =
openIndex(
internal_xact,
TransactionController.MODE_TABLE,
LockingPolicy.MODE_CONTAINER);
DataValueDescriptor[] shrink_key =
purgeCommittedDeletes(open_btree, this.page_number);
// RESOLVE (mikem) - move this call when doing row level locking.
if (shrink_key != null)
doShrink(open_btree, shrink_key);
open_btree.close();
}
catch (StandardException se)
{
// 2 kinds of errors here expected here. Either container not
// found or could not obtain lock (LOCK_TIMEOUT or DEADLOCK).
//
// It is possible by the time this post commit work gets scheduled
// that the container has been dropped and that the open container
// call will return null - in this case just return assuming no
// work to be done.
if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT) ||
se.getMessageId().equals(SQLState.DEADLOCK))
{
// Could not get exclusive table lock, so try row level
// reclaim of just the rows on this page. No merge is
// attempted.
try
{
open_btree =
openIndex(
internal_xact,
TransactionController.MODE_RECORD,
LockingPolicy.MODE_RECORD);
purgeRowLevelCommittedDeletes(open_btree);
open_btree.close();
}
catch (StandardException se2)
{
if (se2.getMessageId().equals(SQLState.LOCK_TIMEOUT) ||
se2.getMessageId().equals(SQLState.DEADLOCK))
{
// Could not get intended exclusive table lock, so
// requeue and hope other user gives up table level
// lock soon. This should not be normal case.
requeue_work = true;
}
}
}
}
finally
{
internal_xact.commit();
internal_xact.destroy();
}
return(requeue_work ? Serviceable.REQUEUE : Serviceable.DONE);
}