--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.raw.xact.RowLocking3\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.raw.xact;\r
+\r
+import org.apache.derby.iapi.services.locks.LockFactory;\r
+import org.apache.derby.iapi.services.locks.C_LockFactory;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.store.raw.ContainerHandle;\r
+import org.apache.derby.iapi.store.raw.ContainerLock;\r
+import org.apache.derby.iapi.store.raw.RecordHandle;\r
+import org.apache.derby.iapi.store.raw.RowLock;\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+import org.apache.derby.iapi.store.raw.LockingPolicy;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+\r
+/**\r
+ A locking policy that implements row level locking with isolation degree 3.\r
+\r
+ @see org.apache.derby.iapi.store.raw.LockingPolicy\r
+*/\r
+public class RowLocking3 extends NoLocking \r
+{\r
+ // no locking has no state, so it's safe to hold\r
+ // it as a static\r
+ private static final LockingPolicy NO_LOCK = new NoLocking();\r
+\r
+ protected final LockFactory lf;\r
+\r
+ protected RowLocking3(LockFactory lf) \r
+ {\r
+ this.lf = lf;\r
+ }\r
+\r
+ /**\r
+ * Get type of lock to get while reading data.\r
+ * <p>\r
+ * This routine is provided so that class's like RowLockingRR can\r
+ * override just this routine to get RS2 locks vs RS3 locks, and still\r
+ * reuse all the other code in this class.\r
+ * <p>\r
+ *\r
+ * @return The lock type of a shared lock for this locking policy.\r
+ **/\r
+ protected RowLock getReadLockType() \r
+ {\r
+ return(RowLock.RS3);\r
+ }\r
+\r
+ /**\r
+ * Get type of lock to get while requesting "update" lock.\r
+ * <p>\r
+ * This routine is provided so that class's like RowLockingRR can\r
+ * override just this routine to get RU2 locks vs RU3 locks, and still\r
+ * reuse all the other code in this class.\r
+ * <p>\r
+ *\r
+ * @return The lock type of a shared lock for this locking policy.\r
+ **/\r
+ protected RowLock getUpdateLockType() \r
+ {\r
+ return(RowLock.RU3);\r
+ }\r
+\r
+ /**\r
+ * Get type of lock to get while writing data.\r
+ * <p>\r
+ * This routine is provided so that class's like RowLockingRR can\r
+ * override just this routine to get RX2 locks vs RX3 locks, and still\r
+ * reuse all the other code in this class.\r
+ * <p>\r
+ *\r
+ * @return The lock type of a shared lock for this locking policy.\r
+ **/\r
+ protected RowLock getWriteLockType() \r
+ {\r
+ return(RowLock.RX3);\r
+ }\r
+\r
+\r
+ /**\r
+ * Obtain container level intent lock.\r
+ * <p>\r
+ * This implementation of row locking is 2 level, ie. table and row locking.\r
+ * It will interact correctly with tables opened with ContainerLocking3\r
+ * locking mode.\r
+ * <p>\r
+ * Updater's will get table level IX locks, and X row locks.\r
+ * <p>\r
+ * Reader's will get table level IS locks, and S row locks.\r
+ *\r
+ * @param t Transaction to associate lock with.\r
+ * @param container Container to lock.\r
+ * @param waitForLock Should lock request wait until granted?\r
+ * @param forUpdate Should container be locked for update, or read?\r
+ *\r
+ * @return true if the lock was obtained, false if it wasn't. \r
+ * False should only be returned if the waitForLock policy was set to\r
+ * "false," and the lock was unavailable.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public boolean lockContainer(\r
+ Transaction t, \r
+ ContainerHandle container, \r
+ boolean waitForLock,\r
+ boolean forUpdate)\r
+ throws StandardException \r
+ {\r
+ Object qualifier = forUpdate ? ContainerLock.CIX : ContainerLock.CIS;\r
+\r
+ boolean gotLock = \r
+ lf.lockObject(\r
+ t.getCompatibilitySpace(), t, container.getId(), qualifier,\r
+ waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT);\r
+\r
+ if (gotLock) {\r
+ // look for covering table locks\r
+ // CIS is covered by CX or CS\r
+ // CIX is covered by CX\r
+\r
+ if (lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CX) ||\r
+ ((!forUpdate) && lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CS))) {\r
+\r
+\r
+ container.setLockingPolicy(NO_LOCK);\r
+ }\r
+ }\r
+\r
+ return gotLock;\r
+\r
+ }\r
+\r
+\r
+ /**\r
+ * Obtain lock on record being read.\r
+ * <p>\r
+ * Assumes that a table level IS has been acquired. Will acquire a Shared\r
+ * or Update lock on the row, depending on the "forUpdate" parameter.\r
+ * <p>\r
+ *\r
+ * @param t The transaction to associate the lock with.\r
+ * @param record The record to be locked.\r
+ * @param waitForLock Should lock request wait until granted?\r
+ * @param forUpdate Whether to open for read or write access.\r
+ *\r
+ * @return true if the lock was granted, false if waitForLock was false \r
+ * and the lock could not be granted.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public boolean lockRecordForRead(\r
+ Transaction t, \r
+ ContainerHandle container_handle,\r
+ RecordHandle record, \r
+ boolean waitForLock,\r
+ boolean forUpdate)\r
+ throws StandardException\r
+ {\r
+ // RESOLVE - Did I do the right thing with the "forUpdate" variable.\r
+\r
+ // For now just lock the row in Shared mode.\r
+ Object qualifier = forUpdate ? getUpdateLockType() : getReadLockType();\r
+\r
+ return(\r
+ lf.lockObject(\r
+ t.getCompatibilitySpace(), t, record, qualifier,\r
+ waitForLock ? \r
+ C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT));\r
+ }\r
+\r
+ /**\r
+ * Obtain lock on record being written.\r
+ * <p>\r
+ * Assumes that a table level IX has been acquired. Will acquire an\r
+ * Exclusive (X) lock on the row.\r
+ * <p>\r
+ *\r
+ * @param t transaction to associate the lock with.\r
+ * @param record The record to be locked.\r
+ * @param lockForInsertPreviousKey Lock is for a previous key of a insert.\r
+ * @param waitForLock Should lock request wait until granted?\r
+ *\r
+ * @return true if the lock was granted, false if waitForLock was false \r
+ * and the lock could not be granted.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public boolean zeroDurationLockRecordForWrite(\r
+ Transaction t, \r
+ RecordHandle record,\r
+ boolean lockForInsertPreviousKey,\r
+ boolean waitForLock)\r
+ throws StandardException\r
+ {\r
+ return(lf.zeroDurationlockObject(\r
+ t.getCompatibilitySpace(), record, \r
+ (lockForInsertPreviousKey ? RowLock.RIP : getWriteLockType()),\r
+ waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT));\r
+ }\r
+\r
+ /**\r
+ * Obtain lock on record being written.\r
+ * <p>\r
+ * Assumes that a table level IX has been acquired. Will acquire an\r
+ * Exclusive (X) lock on the row.\r
+ * <p>\r
+ *\r
+ * @param t The transaction to associate the lock with.\r
+ * @param record The record to be locked.\r
+ * @param lockForInsert Lock is for an insert.\r
+ * @param waitForLock Should lock request wait until granted?\r
+ *\r
+ * @return true if the lock was granted, false if waitForLock was false \r
+ * and the lock could not be granted.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public boolean lockRecordForWrite(\r
+ Transaction t, \r
+ RecordHandle record,\r
+ boolean lockForInsert,\r
+ boolean waitForLock)\r
+ throws StandardException\r
+ {\r
+ return(lf.lockObject(\r
+ t.getCompatibilitySpace(), t, record, \r
+ lockForInsert ? RowLock.RI : getWriteLockType(),\r
+ waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT));\r
+ }\r
+\r
+ public int getMode() {\r
+ return MODE_RECORD;\r
+ }\r
+\r
+\r
+ /*\r
+ ** We can inherit all the others methods of NoLocking since we hold the \r
+ ** container lock and row locks until the end of transaction.\r
+ */\r
+}\r