• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Locking on a static object

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I'm wondering if anyone can help with this locking design problem.

My design uses multiple copies of Data class and I'm trying to support multiple databases. I have a lock manager (inside data) that holds a non-static hashmap of locked records.

I wish to synchronise the methods of the lockmanager i.e lock, unlock, isLocked etc.

In order to do this in a multithreaded environment I believe that I need to synchronise on a shared variable. However!!! I've read several folks designs on this website and a lot of them use a shared static variable even when they claim to have a multi table design. I've been thinking that a shared static variable inside data or even lockmanager will not work very well since this means that clients need to wait on the variable even if they are not operating on the same database. What I really need is a variable that is held 1 per table such as the db filename.

Am I correct with this reasoning? How did other folks synchronize in their multi table designs?

thanks
Chris
 
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

How did other folks synchronize in their multi table designs?


Hi Chris,

I don't think many people have a design that supports multiple tables. At least I didn't and I am quite sure it will be beyond the scope of the assignment. You can safely assume that your server will need to 'serve' only one file at any given moment. You would probably even be violating some instructions (the ones about that the user shall be able to specify the database file location) if you were to support multi-file serving.

Frans.
 
Chris Blake
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the reply Frans,

Can I ask if you used multiple instances of Data? i.e 1 per user connection.

If you did not use multiple instances of Data, then how did you perform the locking of records?

thanks,
Chris
 
Frans Janssen
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Chris,

I used multiple instances of Data (one for each connected client). I did locking on record-level: I had a singleton-collection of objects representing the records. A client wanting to lock on a record, must synchronize on the record lock object, so that multiple clients can never be granted the lock simultaneously.

I have seen many people here having a design where they synchronize on an object representing the database (of course this cannot be the Data class if you have multiple instances of that one). Although this seemed inefficient to me, I would consider such a design if I had to do it all over again, because of the reduced complexity.

Frans.
 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I also used multiple instances of my Data class.

This contained a static hashmap in which I stored references to locked records, and this is what I synchronized on for the actual locking.

Originally, I supplied a RandomAccessFile for each Data instance, but I was persuaded to make this static also.

This is because of potential problems due to concurrent updates to the db file.

So now, to update a record, I lock a record, perform a synchronized read, perform a synchronised write and unlock.

The synchronized read and write is to prevent more than one client attempting to read or write from/to the file concurrently.

If you did not use multiple instances of Data, then how did you perform the locking of records?



One way would be to make Data a singleton, so there is only one instance for all clients, and make the hashmap non static.

Then synchronize on this hashmap as above.
 
Chris Blake
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It does get confusing trying to understand everyones ideas, but here is my design and a few reasons why: -

* Nothing is static in the server side (At least nothing in Data, or LockManager, or Service)
* Nothing is Singleton.

Lots of reasons behind this, but mainly because if you make anything static appart from stuff which really really needs to be shared across all databases, then its not a true flexible multi table design.
Same goes for Singleton.

Christy in your design you say that you have a static RandomAccessFile object. Now how do you expect to be able to handle multiple table/databases when the variable is static. You would need one static variable/table/file
in order to handle multiple databases. This is only if you are intending to mention the multi-table capability? I assume you are not intending to do a flexible multi-table design?


My design is like this: -

Service(Data(LockManager(Hashmap)))

Each user has a unique service stub which uses a unique Data object.
The Data object uses a lockManager object that is 1 per table/per database file (See not static or singleton)

Program Flow
------------

1) Server binds databaseFactory to RMI registry
2) Client Looks up databaseFactory and gets stub
3) Client uses databaseFactory.getDB(String dbFilename) to get Service Stub
4) Server looks up a hashmap to see if the table is already open if yes then return the existing lockManager
else create a new lockManager for this table and insert into the hashmap with dbFilename as key. return it.
Server then calls return new Service(new Data(dbFilename, lockMgr));

I'm not critising anyones design but thought you might get something out of this hopefully. Critise mine if you
like, that shall help me improve it.

I think I've got my design finalized.


thanks,
Chris
 
Frans Janssen
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Chris,

Your design sounds fine. Just so I can be a real pain in the behind one remark:

4) Server looks up a hashmap to see if the table is already open if yes then return the existing lockManager
else create a new lockManager for this table and insert into the hashmap with dbFilename as key.



This smells like singleton to me!

The only difference to this design and mine is that I have only one singleton object, because I have only one database file, and that you have a collection of singletons for your collection of database files.

As I already pointed out, you probably won't be able to apply your flexibile design to its full powers without breaking the rules of the assignment. Personally I wouldn't bother (no extra points to score!), but I respect your endeavour for making it more generic.

Frans.
 
Chris Blake
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hahhaha!

Good one Frans! I'd say its more like a restrictive Factory pattern though because I have no restrictions on how many LockManagers exist in my application or JVM. I.e LockManager constructor is public, but the server controls which lockManagers are generated for each table. i.e 1 per table.

The original problem that I posted about I've now solved just by talking about it and rehashing it through my head! I'm going to synchronize on the non-static hashmap inside the lockManager. This way, no 2 clients can attempt to read the locks of the same specific database table while a lock is being written and vice versa.

thanks
Chris.
reply
    Bookmark Topic Watch Topic
  • New Topic