001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: ReadCommittedLocker.java,v 1.6.2.4 2008/01/07 15:14:17 cwl Exp $
007: */
008:
009: package com.sleepycat.je.txn;
010:
011: import com.sleepycat.je.DatabaseException;
012: import com.sleepycat.je.dbi.CursorImpl;
013: import com.sleepycat.je.dbi.DatabaseImpl;
014: import com.sleepycat.je.dbi.EnvironmentImpl;
015: import com.sleepycat.je.tree.BIN;
016: import com.sleepycat.je.tree.Key;
017:
018: /**
019: * Extends BuddyLocker to acquire write locks using the buddy locker (the
020: * transaction locker). This is used for ReadCommitted (Degree 2) isolation.
021: */
022: public class ReadCommittedLocker extends BuddyLocker {
023:
024: /**
025: * Creates a ReadCommittedLocker.
026: * @param buddy is a transactional locker that will be used for acquiring
027: * write locks.
028: */
029: public ReadCommittedLocker(EnvironmentImpl env, Locker buddy)
030: throws DatabaseException {
031:
032: /*
033: * If the buddy param is a read-committed locker, reach in to get its
034: * transactional buddy locker.
035: */
036: super (
037: env,
038: (buddy instanceof ReadCommittedLocker) ? ((ReadCommittedLocker) buddy)
039: .getBuddy()
040: : buddy);
041:
042: assert getBuddy().isTransactional();
043: }
044:
045: /**
046: * Creates a new instance of this txn for the same environment. No
047: * transactional locks are held by this object, so no locks are retained.
048: * newNonTxnLocker is also called for the BuddyLocker.
049: */
050: public Locker newNonTxnLocker() throws DatabaseException {
051:
052: return new ReadCommittedLocker(envImpl, getBuddy()
053: .newNonTxnLocker());
054: }
055:
056: /**
057: * Forwards write locks to the buddy locker (the transaction locker).
058: *
059: * @see Locker#lockInternal
060: * @Override
061: */
062: LockResult lockInternal(long nodeId, LockType lockType,
063: boolean noWait, DatabaseImpl database)
064: throws DatabaseException {
065:
066: if (lockType.isWriteLock()) {
067: return getBuddy().lockInternal(nodeId, lockType, noWait,
068: database);
069: } else {
070: return super .lockInternal(nodeId, lockType, noWait,
071: database);
072: }
073: }
074:
075: /**
076: * Releases the lock from this locker, or if not owned by this locker then
077: * releases it from the buddy locker.
078: */
079: public void releaseLock(long nodeId) throws DatabaseException {
080:
081: if (!lockManager.release(nodeId, this )) {
082: lockManager.release(nodeId, getBuddy());
083: }
084: removeLock(nodeId);
085: }
086:
087: /**
088: * Forwards this method to the transactional buddy. Since the buddy
089: * handles write locks, it knows whether this transaction created the node.
090: */
091: public boolean createdNode(long nodeId) throws DatabaseException {
092:
093: return getBuddy().createdNode(nodeId);
094: }
095:
096: /**
097: * Forwards this method to the transactional buddy. The buddy handles
098: * write locks and therefore handles abort information.
099: */
100: public long getAbortLsn(long nodeId) throws DatabaseException {
101:
102: return getBuddy().getAbortLsn(nodeId);
103: }
104:
105: /**
106: * @return the WriteLockInfo for this node.
107: */
108: public WriteLockInfo getWriteLockInfo(long nodeId)
109: throws DatabaseException {
110:
111: return getBuddy().getWriteLockInfo(nodeId);
112: }
113:
114: /**
115: * Forwards this method to the transactional buddy. The buddy handles
116: * write locks and therefore handles delete information.
117: */
118: public void addDeleteInfo(BIN bin, Key deletedKey)
119: throws DatabaseException {
120:
121: getBuddy().addDeleteInfo(bin, deletedKey);
122: }
123:
124: /**
125: * Forwards this method to the transactional buddy. The buddy Txn tracks
126: * cursors.
127: */
128: public void registerCursor(CursorImpl cursor)
129: throws DatabaseException {
130:
131: getBuddy().registerCursor(cursor);
132: }
133:
134: /**
135: * Forwards this method to the transactional buddy. The buddy Txn tracks
136: * cursors.
137: */
138: public void unRegisterCursor(CursorImpl cursor)
139: throws DatabaseException {
140:
141: getBuddy().unRegisterCursor(cursor);
142: }
143:
144: /**
145: * Is always transactional because the buddy locker is transactional.
146: */
147: public boolean isTransactional() {
148: return true;
149: }
150:
151: /**
152: * Is always read-committed isolation.
153: */
154: public boolean isReadCommittedIsolation() {
155: return true;
156: }
157: }
|