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

[URLyBird 1.1.3]: Alternate Locking solution

 
Martin Sturzenhecker
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everybody,

my assignment is URLyBird 1.1.3 which means I have to use cookieIDs.

The overall server architecture is as follows:

  • I use rmi.
  • I use J2SE 5.0
  • A ConnectionFactory is the only Object bound to the registry.
  • Each client has to connect to the database using the factory.
  • Each client has its own unique RemoteData, which is a remote adapter to Data.
  • Data is "multiton" to support different database files.
  • The keys in the lockedRecords map are record ids.


  • I do not utilize the common approach to synchronize on lockedRecords. Instead my LockHandler looks like this (just a sketch):

    Additionally - to handle client crashes - RemoteData implements Unreferenced and keeps track of the records this instance locked.

    What do you think?
    Will it work? -- My tests indicate it will.
    Is it too elaborate?

    I chose this locking implementation because
  • I like the idea of record ids being lockedRecords' keys,
  • I think it behaves more reliably and is more efficient than synching on lockedRecords,
  • I wanted to use (aka play with) some Java 5.0 features.



  • Comments are very welcome.

    cheers
    martin

    [ December 11, 2005: Message edited by: Martin Sturzenhecker ]

    [ December 12, 2005: Message edited by: Martin Sturzenhecker ]

    December 14, 2005: Message edited: Reformatted "CODE" section.
    [ December 14, 2005: Message edited by: Martin Sturzenhecker ]
     
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander
    Pie
    Posts: 12012
    218
    C++ Firefox Browser IntelliJ IDE Java Mac Oracle
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Martin,

    Your basic concept looks good, and several other forum members have recently been developing similar concepts (although I don't think I have seen anyone use the Semaphore class for this purpose - even though it is ideal).

    Just some general pickiness though...

    You mentioned that Data is a multiton. But what happens if you have two instances of Data and clients want to lock record number 4 in both tables?

    I would recommend against hard coding magic numbers, e.g.:Whoever supports your code may not know what the parameters are for this - it would be better to have a separate variable (or even a constant). Take a look at the sample code in the API documentation for an example.

    Regards, Andrew
     
    Martin Sturzenhecker
    Greenhorn
    Posts: 23
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Andrew,

    thank you for your reply.

    I don't see a problem using a counting Semaphore, where just one semaphhore is available. A RecordSemaphore is unique to a database file and record number.



    Maybe Data isn't a multiton then, is it?

    I will have closer look at the sample code though and repost later (lack of time ... ...

    regards
    -martin

    [ December 14, 2005: Message edited by: Martin Sturzenhecker ]
    [ December 14, 2005: Message edited by: Martin Sturzenhecker ]
     
    Martin Sturzenhecker
    Greenhorn
    Posts: 23
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Andrew,

    it seems I missed your point in my previous post.



    Data simply delegates calls to locky and fily.


    So a Map.Entry in locky.semaphores represents a single record and its associated lock (cookie and semaphore) of a single data file. There can be only 1 such semaphore.

    Is this class collaboration too complex ?

    Do I still miss your point?
    If this is the case you must use a simpler wording so my humble non-native english mind can follow ;-)

    regards
    martin

    [ December 14, 2005: Message edited by: Martin Sturzenhecker ]
    [ December 14, 2005: Message edited by: Martin Sturzenhecker ]
     
    jiju ka
    Ranch Hand
    Posts: 308
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I have one question on this design

    When you do an insert you probably will create a new Semophore and add it to the collection - semophores.

    If two users are doing inserts concurrently how do you ensure that recno's generated by two users are unique?

    Below are the steps you will be executing to do an insert.

    Get number of records
    curr record num <--- add one to number of records
    new sempophore <-- new Semophore for curr record num
    acquire lock
    insert record to physical table
    release lock

    The operations starting from "creating rec number" through "write" need to be synchronized without giving chance to dead locks.
    [ December 19, 2005: Message edited by: jiju ka ]
     
    Martin Sturzenhecker
    Greenhorn
    Posts: 23
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Jiju,

    thanks for your reply

    Below are the steps you will be executing to do an insert.

    Get number of records
    curr record num <--- add one to number of records
    new sempophore <-- new Semophore for curr record num
    acquire lock
    insert record to physical table
    release lock

    The operations starting from "creating rec number" through "write" need to be synchronized without giving chance to dead locks.


    I do not generate a lock for a new record. A record that doesn't exist yet has no need to get locked.

    So my steps are:

    Insert record to physical table (possibly reusing a deleted entry).

    You are right, the insertion and record position calculation has to be synchronized.

    regards
    -martin
     
    jiju ka
    Ranch Hand
    Posts: 308
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks for your reply. After thinking a while I find physical record-insertion is not an issue.
    In most cases you will be doing update. i.e for booking.

    You will be doing logical inserts to add a new room. Physical insertion happens only when the deleted records gets used up.

    So in what mode you will add new room. Standalone mode is most appropriate. It you do it in network mode, it will not be easy to attain concurrency.
    Further adding a new room is not a "must". Do you agree with me? Sorry for the confusion.
     
    Martin Sturzenhecker
    Greenhorn
    Posts: 23
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Jiju,

    Originally posted by jiju ka:

    So in what mode you will add new room. Standalone mode is most appropriate. It you do it in network mode, it will not be easy to attain concurrency.
    Further adding a new room is not a "must".


    Since adding new rooms (as well as deleting rooms) is not a must, I will not support it (in the GUI). The application we are to implement assists CSRs and their job is to sale accomodations, not maintaining data.

    Nevertheless my Data implementation supports add/delete operations. Concurrency for these ops is attained by synchronising (small code sections) on the data instance.

    I hope my answer is useful.

    regards,
    -martin
     
    jiju ka
    Ranch Hand
    Posts: 308
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Concurrency for these ops is attained by synchronising (small code sections) on the data instance.


    I agree with you.
    I hope you are going to maintain a single data instance (singleton) at server side.

    Sorry, I missed the point that create method must be implemented eventhough new Room use case is not a must.

    So for logical update and logical deletion you do record level locking. For insert you do file level locking.
     
    Slava Garin
    Greenhorn
    Posts: 3
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hello, Martin.
    One question about your design. Do you remove semaphore from map after releasing? If so, can you please show pseudo-code snippet how you do that (with synchronization blocks)? I'm really got stuck with removing-semaphores-form-map. Every solution I have in mind either can goes to deadlock or dubbed semaphore creation . Thanks!
     
    Martin Sturzenhecker
    Greenhorn
    Posts: 23
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi everybody,

    sorry for being offline a few days.

    @Jiju: The only locking I do is like in . Using the sync'ed blocks ensures only one caller can write to the file at a time. Calls to read are not sync'ed.

    @Slava: I do not remove record semaphores. So, after some warm up time every record will have a semaphore in the map. This semaphore may have permits available (unlocked) or not (locked). My tests didn't reveal any deadlocks or dubbed semaphores yet. Which map do you use? I use a ConcurrentMap, which has atomic "compare and set" methods. I found these very useful.

    Merry Christmas
    -martin
     
    Slava Garin
    Greenhorn
    Posts: 3
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hello, Martin. Thanks for you answer.

    I'm using regular HashMap (because of jdk 1.4), so my lock function looks like this:

    Same synchronization in unlock function.
    I was wondering where I can remove lock from the map, but never mind, let's leave them, it's not so bad
    Thanks again!
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic