/* * Process a request of a lock for the variable with @variableIndex * @transactionNumber is the transaction number of the trasaction requesting the lock * @isLockRequestReadOnly refers to the type of lock to request * @return the lock or null if not successful * */ public Lock requestLock( int currentTimestamp, int transactionNumber, int variableIndex, boolean isLockRequestReadOnly) { Lock candidateLock = new Lock(transactionNumber, this.siteIndex, variableIndex, isLockRequestReadOnly); for (Lock lock : this.activeLocks) { // Loop through all the active locks. // If there is a write lock already on @variableIndex, no other transaction may access it, so // return null // If a different transaction has a read lock and the requesting lock is a write lock, do not // give the lock i.e. return null if ((lock.getTransactionNumber() != transactionNumber && lock.getLockedVariableIndex() == variableIndex && !lock.isReadOnly()) || (lock.getTransactionNumber() != transactionNumber && lock.getLockedVariableIndex() == variableIndex && lock.isReadOnly() && !isLockRequestReadOnly)) { System.out.println( "Site: T" + transactionNumber + " found conflicting lock held by T" + lock.getTransactionNumber()); System.out.println( "Site: " + (isLockRequestReadOnly ? "Read" : "Exclusive") + " Lock denied for T" + transactionNumber + " on x" + variableIndex + "." + siteIndex); return null; } } // At this point, the check is successful and add the lock to the active locks this.activeLocks.add(candidateLock); System.out.println( "Site: " + (isLockRequestReadOnly ? "Read" : "Exclusive") + " Lock give to T" + transactionNumber + " on x" + variableIndex + "." + siteIndex); // Give lock and record in the site String[] details = new String[] { "give lock", "" + transactionNumber, "" + variableIndex, "" + isLockRequestReadOnly }; siteLog.addEvent(currentTimestamp, details); // Return the lock to the requesting transaction return candidateLock; }
/* * Process an upgrade request of a lock from read to exclusive for the variable with @variableIndex * @transactionNumber is the transaction number of the transaction requesting the lock * @return the lock or null if not successful * */ public Lock upgradeRequest(int currentTimestamp, int transactionNumber, int variableIndex) { Lock candidateLock = new Lock(transactionNumber, this.siteIndex, variableIndex, false); for (Lock lock : this.activeLocks) { // Loop through all the active locks. // If there is a write lock already on @variableIndex, no other transaction may access it, so // return null // If a different transaction has a read lock and the requesting lock is a write lock, do not // give the lock i.e. return null if ((lock.getTransactionNumber() != transactionNumber && lock.getLockedVariableIndex() == variableIndex && !lock.isReadOnly()) || (lock.getTransactionNumber() != transactionNumber && lock.getLockedVariableIndex() == variableIndex && lock.isReadOnly())) { System.out.println( "Site: T" + transactionNumber + " found conflicting lock held by T" + lock.getTransactionNumber()); System.out.println( "Site: Upgrade to exclusive lock denied for T" + transactionNumber + " on x" + variableIndex + "." + siteIndex); return null; } } // If successful, remove the lock from the activeLocks and add the candidate to the activeLocks int index = 0; while (index < this.activeLocks.size()) { if (this.activeLocks.get(index).getLockedVariableIndex() == variableIndex && this.activeLocks.get(index).getTransactionNumber() == transactionNumber) { this.activeLocks.remove(index); break; } index++; } this.activeLocks.add(candidateLock); System.out.println( "Site: Upgrade to exclusive lock give to T" + transactionNumber + " on x" + variableIndex + "." + siteIndex); // Give lock and record in the site String[] details = new String[] {"give lock", "" + transactionNumber, "" + variableIndex, "" + false}; siteLog.addEvent(currentTimestamp, details); return candidateLock; }
/* * Return the lock that is conflicting with a hypothetical lock of the following properties: * @transactionNumber is the transaction number of the transaction requesting the lock * @variableIndex is the variable index the hypothetical lock would hold on * @isLockRequestReadOnly refers to the type of the hypothetical lock * @return the lock or null if not successful */ public Lock getConflictingLock( int transactionNumber, int variableIndex, boolean isLockRequestReadOnly) { for (Lock lock : this.activeLocks) { // Loop through all the active locks. // If there is a conflicting lock on @variableIndex, return that lock if ((lock.getTransactionNumber() != transactionNumber && lock.getLockedVariableIndex() == variableIndex && !lock.isReadOnly()) || (lock.getTransactionNumber() != transactionNumber && lock.getLockedVariableIndex() == variableIndex && lock.isReadOnly() && !isLockRequestReadOnly)) { return lock; } } return null; }
/* * Release all locks for a particular transaction from @activeLocks * @transactionNumber refers to the transaction in which his locks should be released */ public void releaseLocks(int transactionNumber, int currentTimestamp) { int i = 0; while (i < this.activeLocks.size()) { Lock lock = this.activeLocks.get(i); if (lock.getTransactionNumber() == transactionNumber) { System.out.println( "Site: Release lock from T" + transactionNumber + " on x" + lock.getLockedVariableIndex() + "." + siteIndex); // Give lock and record in the site String[] details = new String[] { "release lock", "" + transactionNumber, "" + lock.getLockedVariableIndex(), "" + lock.isReadOnly() }; siteLog.addEvent(currentTimestamp, details); this.activeLocks.remove(lock); } else { if (debug) System.out.println( "Site: Lock not released on x" + lock.getLockedVariableIndex() + "." + siteIndex + " held by T" + lock.getTransactionNumber()); i++; } } }