// create the first alloc page and the first user page,
// if this fails for any reason the transaction
// will roll back and the container will be dropped (removed)
ContainerHandle containerHdl = null;
Page firstPage = null;
try
{
// if opening a temporary container with IS_KEPT flag set,
// make sure to open it with IS_KEPT too.
if (tmpContainer &&
((temporaryFlag & TransactionController.IS_KEPT) ==
TransactionController.IS_KEPT))
{
mode |= ContainerHandle.MODE_TEMP_IS_KEPT;
}
// open no-locking as we already have the container locked
containerHdl =
t.openContainer(
identity, null, (ContainerHandle.MODE_FORUPDATE | mode));
// we just added it, containerHdl should not be null
if (SanityManager.DEBUG)
SanityManager.ASSERT(containerHdl != null);
if (!tmpContainer)
{
// make it persistent (in concept if not in reality)
RawContainerHandle rch = (RawContainerHandle)containerHdl;
ContainerOperation lop =
new ContainerOperation(rch, ContainerOperation.CREATE);
// mark the container as pre-dirtied so that if a checkpoint
// happens after the log record is sent to the log stream, the
// cache cleaning will wait for this change.
rch.preDirty(true);
try
{
t.logAndDo(lop);
// flush the log to reduce the window between where
// the container is created & synced and the log record
// for it makes it to disk. If we fail in this
// window we will leave a stranded container file.
flush(t.getLastLogInstant());
}
finally
{
// in case logAndDo fail, make sure the container is not
// stuck in preDirty state.
rch.preDirty(false);
}
}
firstPage = containerHdl.addPage();
}
finally
{
if (firstPage != null)
{
firstPage.unlatch();
firstPage = null;
}
containerCache.release(container);