/* * create a container that all threads can use */ private long commonContainer() throws T_Fail { ContextManager cm1 = contextService.newContextManager(); contextService.setCurrentContextManager(cm1); long cid; try { Transaction t = t_util.t_startTransaction(); cid = t_util.t_addContainer(t, 0); t_util.t_commit(t); t.close(); } catch (StandardException se) { cm1.cleanupOnError(se); throw T_Fail.exceptionFail(se); } finally { contextService.resetCurrentContextManager(cm1); } return cid; }
/** * Obtain container level intent lock. * * <p>This implementation of row locking is 2 level, ie. table and row locking. It will interact * correctly with tables opened with ContainerLocking3 locking mode. * * <p>Updater's will get table level IX locks, and X row locks. * * <p>Reader's will get table level IS locks, and S row locks. * * <p>Read locks are put in a separate "group" from the transaction, so that when the container is * closed it can release these read locks. * * @param t Transaction to associate lock with. * @param container Container to lock. * @param waitForLock Should lock request wait until granted? * @param forUpdate Should container be locked for update, or read? * @return true if the lock was obtained, false if it wasn't. False should only be returned if the * waitForLock policy was set to "false," and the lock was unavailable. * @exception StandardException Standard exception policy. */ public boolean lockContainer( Transaction t, ContainerHandle container, boolean waitForLock, boolean forUpdate) throws StandardException { Object qualifier = forUpdate ? ContainerLock.CIX : ContainerLock.CIS; // for cursor stability put read locks on a separate lock chain, which // will be released when the container is unlocked. Object group = forUpdate ? ((Object) t) : ((Object) container.getUniqueId()); boolean gotLock = lf.lockObject( t.getCompatibilitySpace(), group, container.getId(), qualifier, waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT); if (gotLock) { // look for covering table locks // CIS and CIX is covered by CX // In that case move the lock to the transaction list from the // container list, as the null locking policy will do nothing in // unlockContainer(). // if (lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CX)) { // release any container group locks becuase CX container lock will cover everthing. lf.unlockGroup(t.getCompatibilitySpace(), container.getUniqueId()); container.setLockingPolicy(NO_LOCK); } else if ((!forUpdate) && lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CS)) { // move locks from container group to transaction group. lf.transfer(t.getCompatibilitySpace(), group, t); container.setLockingPolicy(NO_LOCK); } } return gotLock; }
/** * Obtain lock on record being read. * * <p>Assumes that a table level IS has been acquired. Will acquire a Shared or Update lock on the * row, depending on the "forUpdate" parameter. * * <p>Read lock will be placed on separate group from transaction. * * @param t The transaction to associate the lock with. * @param record The record to be locked. * @param waitForLock Should lock request wait until granted? * @param forUpdate Whether to open for read or write access. * @return true if the lock was granted, false if waitForLock was false and the lock could not be * granted. * @exception StandardException Standard exception policy. */ public boolean lockRecordForRead( Transaction t, ContainerHandle container_handle, RecordHandle record, boolean waitForLock, boolean forUpdate) throws StandardException { Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2; return (lf.lockObject( t.getCompatibilitySpace(), container_handle.getUniqueId(), record, qualifier, waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT)); }
public void unlockRecordAfterRead( Transaction t, ContainerHandle container_handle, RecordHandle record, boolean forUpdate, boolean row_qualified) throws StandardException { Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2; int count = lf.unlock(t.getCompatibilitySpace(), container_handle.getUniqueId(), record, qualifier); if (SanityManager.DEBUG) { // in the case of lock escalation the count could be 0. if (!(count == 1 || count == 0)) { SanityManager.THROWASSERT( "count = " + count + "record.getContainerId() = " + record.getContainerId()); } } }
/* * create a stream container load with rowCount number of rows. * fetch it all back, and check to make sure all rows are correct. */ protected void SF001(int rowCount, int columnCount, int columnType, boolean forceAbort) throws StandardException, T_Fail { Transaction t = t_util.t_startTransaction(); int segmentId = StreamContainerHandle.TEMPORARY_SEGMENT; Properties properties = new Properties(); properties.put(RawStoreFactory.STREAM_FILE_BUFFER_SIZE_PARAMETER, "16384"); // create row source T_RowSource testRowSource = null; if (forceAbort) testRowSource = new T_RowSource(rowCount, columnCount, columnType, forceAbort, t); else testRowSource = new T_RowSource(rowCount, columnCount, columnType, forceAbort, null); long startms = System.currentTimeMillis(); long containerId = t.addAndLoadStreamContainer(segmentId, properties, testRowSource, null); long endms = System.currentTimeMillis(); long time = endms - startms; REPORT("SF001 - write: " + time + "ms"); // open the container, and start fetching... StreamContainerHandle scHandle = t.openStreamContainer(segmentId, containerId, false); // set up the template row DataValueDescriptor template[] = null; template = testRowSource.getTemplate(); DataValueDescriptor readRow[] = null; readRow = testRowSource.getTemplate(); segmentId = StreamContainerHandle.TEMPORARY_SEGMENT; int fetchCount = 0; startms = System.currentTimeMillis(); ValueRow vReadRow = new ValueRow(readRow.length); while (scHandle.fetchNext(vReadRow)) { fetchCount++; // check to make sure the row is what we inserted. // this depends on T_RowSource generate identical rows. if (!vReadRow.toString().equals(template.toString())) throw T_Fail.testFailMsg( "Record's value incorrect, expected :" + template.toString() + ": - got :" + vReadRow.toString()); } endms = System.currentTimeMillis(); time = endms - startms; // check to make sure we got the right number of rows. if (fetchCount != rowCount) throw T_Fail.testFailMsg( "incorrect number of row fetched. Expecting " + rowCount + " rows, got " + fetchCount + ", rows instead."); REPORT("SF001 - fetch: " + time + "ms"); scHandle.close(); t_util.t_commit(t); t.close(); PASS( "SF001, rowCount = " + rowCount + ", columnCount = " + columnCount + ", clumn type: " + columnType); }
/** * Unlock read locks. * * <p>In Cursor stability release all read locks obtained. unlockContainer() will be called when * the container is closed. * * <p> * * @param t The transaction to associate the lock with. * @param container_handle Container to unlock. */ public void unlockContainer(Transaction t, ContainerHandle container_handle) { // Only release read locks before end of transaction in level 2. lf.unlockGroup(t.getCompatibilitySpace(), container_handle.getUniqueId()); }