/// <summary>
 ///   Date: 10/16/2011
 ///   Adds a lock on behalf of a transaction to the active locks.
 /// </summary>
 /// <param name = "transactionId">The transaction id.</param>
 /// <param name = "operationMode">The operation mode.</param>
 /// <remarks>
 ///   Side effects: the new lock is added to the table entry
 /// </remarks>
 public void AddToActiveLocks(int transactionId, Enumerations.OperationMode operationMode)
 {
     Lock lockToAdd = new Lock(transactionId, operationMode);
     Lock result =
         ActiveLocks.Find(matching => matching.TransactionId == transactionId && matching.Mode == operationMode);
     if (result == null)
         ActiveLocks.Add(lockToAdd);
 }
Beispiel #2
0
 /// <summary>
 ///   11/7/2011
 ///   Checks whether a write lock requests conflicts with existing locks.
 ///   In the case that the item is locked due to recovery, we unlock the item and return false i.e. there are no conflicts.
 /// </summary>
 /// <param name = "requestedLock">The requested lock.</param>
 /// <param name = "entry">The lock table entry to test.</param>
 /// <returns>True if the requested write lock conflicts with any existing locks</returns>
 /// <remarks>
 ///   Side effect: if the lock was held by the LM due to recovery, the lock will be removed
 /// </remarks>
 private bool WriteLockConflicts(Lock requestedLock, LockManagerTableEntry entry)
 {
     int? conflictingTransaction = entry.FindConflictsToWriteLock(requestedLock.TransactionId);
     if (conflictingTransaction == null)
         return false;
     if (conflictingTransaction == int.MinValue)
     {
         entry.RemoveLock(int.MinValue);
         return false;
     }
     return true;
 }
Beispiel #3
0
 /// <summary>
 ///   Date: 10/16/2011
 ///   Checks whether a lock request conflicts with existing locks
 /// </summary>
 /// <param name = "requestedLock">The requested lock.</param>
 /// <param name = "entry">The lock entries entry corresponding to the data item the lock wishes to lock.</param>
 /// <returns>true if requested lock conflicts with any existing locks</returns>
 internal bool LockConflicts(Lock requestedLock, LockManagerTableEntry entry)
 {
     if (requestedLock.Mode == Enumerations.OperationMode.Read)
     {
         if (!ReadLockConflicts(requestedLock, entry)) return false;
     }
     else if (requestedLock.Mode == Enumerations.OperationMode.Write)
     {
         if (!WriteLockConflicts(requestedLock, entry)) return false;
     }
     return true;
 }
Beispiel #4
0
 /// <summary>
 ///   11/7/2011
 ///   Checks whether a read lock request conflicts with existing locks.
 /// </summary>
 /// <param name = "requestedLock">The requested lock.</param>
 /// <param name = "entry">The entry.</param>
 /// <returns>True if the requested read lock conflicts with any existing locks</returns>
 private bool ReadLockConflicts(Lock requestedLock, LockManagerTableEntry entry)
 {
     int? conflictingTransaction = entry.FindConflictsToReadLock(requestedLock.TransactionId);
     if (conflictingTransaction == null)
     {
         return false;
     }
     return true;
 }
Beispiel #5
0
        public void LockConflictsTest()
        {
            LockManager target = new LockManager();
            int transId = 1;
            int dataItem = 1;
            target.Lock(transId, dataItem, Enumerations.OperationMode.Read);
            Lock test = new Lock(transId, Enumerations.OperationMode.Read);
            // lock never conflicts with a lock from its own transaction
            Assert.IsFalse(target.LockConflicts(test, target.lockEntries[dataItem]));
            test = new Lock(transId, Enumerations.OperationMode.Write);
            Assert.IsFalse(target.LockConflicts(test, target.lockEntries[dataItem]));
            test = new Lock(2,Enumerations.OperationMode.Read);
            // two read locks do not conflict
            Assert.IsFalse(target.LockConflicts(test, target.lockEntries[dataItem]));
            test = new Lock(2, Enumerations.OperationMode.Write);
            // A read lock conflicts with a write lock
            Assert.IsTrue(target.LockConflicts(test, target.lockEntries[dataItem]));
            transId = dataItem = 2;

            target.Lock(transId, dataItem, Enumerations.OperationMode.Write);
            // lock never conflicts with a lock from its own transaction
            Assert.IsFalse(target.LockConflicts(test, target.lockEntries[dataItem]));
            test = new Lock(transId, Enumerations.OperationMode.Read);
            Assert.IsFalse(target.LockConflicts(test, target.lockEntries[dataItem]));

            // a write lock or read lock from another transaction always conflicts with an active write lock
            transId = 1;
            test = new Lock(transId, Enumerations.OperationMode.Read);
            Assert.IsTrue(target.LockConflicts(test, target.lockEntries[dataItem]));
            test = new Lock(transId, Enumerations.OperationMode.Write);
            Assert.IsTrue(target.LockConflicts(test, target.lockEntries[dataItem]));

            // reset everything and just test that a recovered lockmanager denies read locks until a write op comes in
            target = new LockManager();
            // mock up what happens in a recovery - this is covered in a unit test in Site
            for (int i = 2; i <= 20; i += 2)
            {
                target.lockEntries[i] = new LockManagerTableEntry();
                target.lockEntries[i].ActiveLocks.Add(new Lock(int.MinValue, Enumerations.OperationMode.Write));
            }

            // try to issue a read op
            transId = 1;
            dataItem = 2;
            test = new Lock(transId, Enumerations.OperationMode.Read);
            Assert.IsTrue(target.LockConflicts(test, target.lockEntries[dataItem]));

            // issue a write op which will work
            test = new Lock(transId, Enumerations.OperationMode.Write);
            Assert.IsFalse(target.LockConflicts(test, target.lockEntries[dataItem]));
        }