In this lab assignment, you will write a lock manager for ColgateDB that provides support for transactions to acquire locks on pages.
See previous labs.
See previous labs.
In this lab assignment, you will write a lock manager for ColgateDB that provides support for transactions to acquire locks on pages.
Your implementation should be written in LockManagerImpl
and it should support the LockManager
interface.
Your implementation should closely follow the description in the Cow book (17.2-17.4). This includes support for shared/exclusive locks and (eventually) deadlock detection. For deadlock detection, you may implement a timeout-based approach or the check for cycles in the waits-for graph (challenge problem!). Note: however that you are not required to implement deadlock detection in this lab. Nevertheless, you should keep it in mind during implementation as it could affect your design decisions (see below).
There are some subtleties that the book does not cover or are worth reiterating. I encourage you to review these periodically when working your implementation:
LockTableEntry
that you may wish to use this in your lock manager. Feel free to modify this class or not use it at all. It will never be accessed outside the lock manager implementation. (It should probably be an inner class of the LockManagerImpl because it’s really an internal data structure. I moved it to a separate class mainly to make the code a little easier to read.)acquireLock
should check whether a lock is available and if not, make the thread wait. But it’s very important that before waiting, the thread should update the lock manager state as appropriate. For example, it should place a lock request in the appropriate queue.TransactionAbortedException
. At this point, you should not release held locks (this will be handled later by code that will catch the thrown exception and rollback any changes made).wait()
to wait and notifyAll()
to alert waiting transaction threads. However, if you use a timeout approach, this probably won’t work. Why not? Each transaction runs in a separate thread and when that thread calls wait()
it will effectively sleep until some other thread calls notifyAll()
. But in the case of deadlock, the deadlocked threads will all be waiting and no one will be active to check whether a timeout has occurred. Thus, if you use the timeout approach, then it is recommended that each thread “busy wait” (see previous lab).There are three unit tests with this lab. Here is a brief description of each:
LockManagerTest
: there is no concurrency in this test class. Instead it is testing that the LockManager state is appropriately updated when locks are acquired and released. It also tests the other helper methods. You can pass all of the tests in this class a fairly simple acquireLock
that simple always grants the lock.ConcurrencyControlTest
: this is very similar to the LockManagerDemo
from last week. A collection of transaction threads are started, each threads repeatedly does the following three steps: (a) acquire an exclusive lock, (b) increment a shared counter, and (c) release the lock. If the LockManagerImpl
is implemented correctly, there should be no thread interference. Note since all threads are acquiring exclusive locks, this does not test any functionality around shared locks, upgrades, etc. Further, only a single item is being locked so there is no deadlock.LockScheduleTest
: this is a test harness designed to more thoroughly test the logic of lock requests. For example, this can be used test that two shared locks can be acquired simultaneously.You are expected to modify these files:
LockManagerImpl.java
LockTableEntry.java
(optional, but recommended)You are expected to read but not modify the other files that were provided.
Task 1 Implement the lock manager! Okay, this is a big task. There are not crisply defined subtasks because it really depends on how you proceed. You might try to work towards the unit tests above, starting with LockManagerTest
, then ConcurrencyControlTest
, and finally LockScheduleTest
. With this strategy, you could start as simple as possible and then revise/refactor your code as you go.
Task 2 Add at least three unit tests to LockScheduleTest
. Include comments that clearly explain the rationale for the test. See upgradeRequestCutsInLine
as an example.
The milestone for this lab will be to complete the above tasks and pass the tests described above.
Upload your files to Gradescope.