package com.sleepycat.je.txn; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.LockStats; import com.sleepycat.je.dbi.CursorImpl; import com.sleepycat.je.dbi.DatabaseImpl; import com.sleepycat.je.dbi.EnvironmentImpl; import com.sleepycat.je.utilint.DbLsn; import de.ovgu.cide.jakutil.*; /** * A concrete Locker that simply tracks locks and releases them when * operationEnd is called. */ public class BasicLocker extends Locker { private Lock ownedLock; private Set ownedLockSet; /** * Creates a BasicLocker. */ public BasicLocker( EnvironmentImpl env) throws DatabaseException { super(env,false,false); } /** * BasicLockers always have a fixed id, because they are never used for * recovery. */ protected long generateId( TxnManager txnManager){ return TxnManager.NULL_TXN_ID; } protected void checkState( boolean ignoreCalledByAbort) throws DatabaseException { } /** * @see Locker#lockInternal * @Override */ LockResult lockInternal( long nodeId, LockType lockType, boolean noWait, DatabaseImpl database) throws DatabaseException { synchronized (this) { checkState(false); } long timeout=0; boolean useNoWait=noWait || defaultNoWait; if (!useNoWait) { synchronized (this) { timeout=lockTimeOutMillis; } } LockGrantType grant=lockManager.lock(nodeId,this,lockType,timeout,useNoWait,database); return new LockResult(grant,null); } /** * Get the txn that owns the lock on this node. Return null if there's no * owning txn found. */ public Locker getWriteOwnerLocker( long nodeId) throws DatabaseException { return lockManager.getWriteOwnerLocker(new Long(nodeId)); } /** * Get the abort LSN for this node in the txn that owns the lock on this * node. Return null if there's no owning txn found. */ public long getOwnerAbortLsn( long nodeId) throws DatabaseException { Locker ownerTxn=lockManager.getWriteOwnerLocker(new Long(nodeId)); if (ownerTxn != null) { return ownerTxn.getAbortLsn(nodeId); } return DbLsn.NULL_LSN; } /** * Is never transactional. */ public boolean isTransactional(){ return false; } /** * Is never serializable isolation. */ public boolean isSerializableIsolation(){ return false; } /** * Is never read-committed isolation. */ public boolean isReadCommittedIsolation(){ return false; } /** * No transactional locker is available. */ public Txn getTxnLocker(){ return null; } /** * Creates a new instance of this txn for the same environment. No * transactional locks are held by this object, so no locks are retained. */ public Locker newNonTxnLocker() throws DatabaseException { return new BasicLocker(envImpl); } /** * Releases all locks, since all locks held by this locker are * non-transactional. */ public void releaseNonTxnLocks() throws DatabaseException { operationEnd(true); } /** * Release locks at the end of the transaction. */ public void operationEnd() throws DatabaseException { operationEnd(true); } /** * Release locks at the end of the transaction. */ public void operationEnd( boolean operationOK) throws DatabaseException { if (ownedLock != null) { lockManager.release(ownedLock,this); ownedLock=null; } if (ownedLockSet != null) { Iterator iter=ownedLockSet.iterator(); while (iter.hasNext()) { Lock l=(Lock)iter.next(); lockManager.release(l,this); } ownedLockSet.clear(); } } /** * Transfer any MapLN locks to the db handle. */ public void setHandleLockOwner( boolean ignore, Database dbHandle, boolean dbIsClosing) throws DatabaseException { if (dbHandle != null) { if (!dbIsClosing) { transferHandleLockToHandle(dbHandle); } unregisterHandle(dbHandle); } } /** * This txn doesn't store cursors. */ public void registerCursor( CursorImpl cursor) throws DatabaseException { } /** * This txn doesn't store cursors. */ public void unRegisterCursor( CursorImpl cursor) throws DatabaseException { } /** * @return the abort LSN for this node. */ public long getAbortLsn( long nodeId) throws DatabaseException { return DbLsn.NULL_LSN; } /** * @return a dummy WriteLockInfo for this node. */ public WriteLockInfo getWriteLockInfo( long nodeId) throws DatabaseException { return WriteLockInfo.basicWriteLockInfo; } /** * Add a lock to set owned by this transaction. */ void addLock( Long nodeId, Lock lock, LockType type, LockGrantType grantStatus) throws DatabaseException { if (ownedLock == lock || (ownedLockSet != null && ownedLockSet.contains(lock))) { return; } if (ownedLock == null) { ownedLock=lock; } else { if (ownedLockSet == null) { ownedLockSet=new HashSet(); } ownedLockSet.add(lock); } } /** * Remove a lock from the set owned by this txn. */ void removeLock( long nodeId, Lock lock) throws DatabaseException { if (lock == ownedLock) { ownedLock=null; } else if (ownedLockSet != null) { ownedLockSet.remove(lock); } } /** * Always false for this txn. */ public boolean createdNode( long nodeId) throws DatabaseException { return false; } /** * A lock is being demoted. Move it from the write collection into the read * collection. */ void moveWriteToReadLock( long nodeId, Lock lock){ } }