Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

my locking scheme

 
Dan Murphy
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I've provisionally decided on the design of my locking scheme and am describing it here in the hope that any flaws in my thinking will be pointed out by the other members. I'm doing the Bogitt & Scarper assignment, version 2.2.2.

As far as reading/writing records is concerned, the scheme is virtually identical to that presented in Max's book. That is, I use:

static Vector recordLocks = new Vector();

which holds a collection of RecordLock objects, each of which is just a record-cookie pair. When locking a record I synchronise on recordLocks, wait() if the record is already locked, and add the RecordLock once the record is available. When unlocking, I synchronise on recordLocks, remove the RecordLock, and notifyAll().

A little additional complexity is introduced by the need to create records and the fact that when creating records, you are allowed to reuse the space occupied by a deleted record. This introduces the following possibilities:

- 2 threads try to simultaneously create a record and write to the same space in the database file
- 2 threads simultaneously creating and deleting the same record (e.g. one thread creates a record and another marks it as deleted before it has been fully created)

I want to prevent both of these situations, but without introducing another object to synchronise on, as this could require nested locks. What I came up with is this:

createRecord() synchronises on recordLocks, and keeps it locked until the record is fully created. This means that only one thread at a time can create records. Unfortunately, it also means that any requests to read/update records that are issued while the record is being created have to wait until after the record has been created (to get the lock on recordLocks). The record-creating thread cannot create the new record in any file positions (i.e. record numbers) that are already in recordLocks, as there is a possibility that these may be in the process of being marked as deleted.

All comments gratefully received!
Cheers,

Dan
 
jiju ka
Ranch Hand
Posts: 308
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Some comments...


I synchronise on recordLocks, wait() if the record is already locked, and add the RecordLock once the record is available.


Are you going to specify a duration to wait for? It is a good practice to specify a wait period considering the fact that a record may remain indefinitely locked under some exceptional conditions not necessarily a programmer error.


- 2 threads try to simultaneously create a record and write to the same space in the database file


While creating a thread it can either reuse a deleted record or grab new space.


This means that only one thread at a time can create records.


While reusing a deleted record for create, you need not apply the above rule.
While grabbing new space there is a workaround to avoid the above rule. You don't have to stop the whole traffic.


static Vector recordLocks = new Vector();

which holds a collection of RecordLock objects, each of which is just a record-cookie pair


From the above quote I feel you are using the record itself to represent the lock. Since there is a 1-1 correspondence between record and record id we can use
record id to lock. So a RecordLock object can have recid and cookie. Say if the cookie is blank the record is not locked.

With this implementation You don't have to put other threads to wait. It can be done as follows

  • 1.Data gets a create message
  • 2.check whether an unused space is available if yes use it; else ...
  • 3.make a new recid in a symchronized method by adding 1 to the max recid
  • 4.In the same synchronized block insert a blank record with delete flag(Reserve space)
  • 5.Now you can create a new recid, cookie pair and say the new record is locked.


  • Synchronization in Steps 3 & 4 is to prevent two threads simultaneously creating records.


    Unfortunately, it also means that any requests to read/update records that are issued while the record is being created have to wait until after the record has been created (to get the lock on recordLocks).

    Please reconsider above statement with the workaround.

    I have a concern over locking for read. I was n't planning to lock to do a read. The possibility of a partially written record being read is very less. I would like to see some test cases which can reproduce this error.

    Meanwhile I created a test case for locking/unlocking. Please see whether you can use it. It can be found at

    [link]http://www.coderanch.com/t/186978/java-developer-SCJD/certification/urlyBird-testing-lock[/link]
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic