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

Unlock/Locking question

 
Jim Janssens
Ranch Hand
Posts: 210
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My question is actually more general, but since I'm having this question related to the SCJD exam I'll post it here. Maybe it can be of use for others.

The assignment specifies an interface for a non relational file database. The operations are: read,update,delete,create . For deleting and updating the records need to be locked first using the lock/unlock methods, which is quite logic. You don't want two threads updating the same record at the same time.

Now,the assignment does not say anything about locking on the read method. But I'm thinking of using the locking mechanism also on the read method. So if someone wants to read a record, it needs to be locked first, after it has been read its unlocked. If the record is allready locked (by the update or delete method) the read method waits untill the record is unlocked.

Ofcourse, when multiple threads operate on the database and threadA locks record 1 for reading, then threadB can still READ it (not update or delete). But, when threadA locks record 1 for updating, then threadB cannot read it until threadA unlocks the record.

Why do I want this ? Assume the following record:
Record1: john, moore,europe (name/lastname/location)

Next assume the following situation:

ThreadA locks record 1 for updating. ThreadA will update the record to "roger, wales, USA" . It starts updating the fist field (it updates john to roger). Next , the JVM decides to run ThreadB. ThreadB wants to read record1. This means that threadB will read the record and has totally screwed up data, since the first field is only updated and the rest belongs to the old record data. So threadB will eventually read: roger, moore, europe. Which is ofcourse totally incorrect.

So, to avoid this I want that records that are locked for update/delete purposes cannot be read until they are unlocked.

Basicly, I could also put synchronize before the read and write methods of the database class. By doing this it will not be possible that a thread reads data while another one is writing data and vica versa.

However, this also means that when ThreadA is writing record 5 and threadB wants to read record 1, threadB has to wait until threadA finishes , while this could go without waiting since it are different records...

What do you guys think about this ? ...
 
peter wooster
Ranch Hand
Posts: 1033
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are two aspects to the locking of records for this assignment.

One is ensuring that the physical accesses to the data, sequences like {seek, read} and {seek, write} are done in a race free manner. This requires that the low level methods that access the data be synchronized on the file.

The second is that sequences such as {read, modify, write} are done in a race free manner. This requires a logical lock on the record so the sequence becomes {lock, read, modify, write, unlock}. Note that this sequence of operations may be done remotely. The {lock, read} action is similar to the Oracle ReadForUpdate action. This locking is done by keeping a map of record numbers that are locked. A thread that wishes to lock a record that is already locked will wait on a resource and will be notified when that resource is freed.
 
Jim Janssens
Ranch Hand
Posts: 210
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, Thanks !

If I understand it correctly, you apply locking on two levels. The lowest level is physical locking using the syncrhonized keywords on the write() and read() methods of the Data class. Meaning that only one thread can read or write at the same time. If threadA is reading and threadB wants to write, then ThreadB needs to wait until threadA finishes and releases the lock. If ThreadA is reading, and ThreadB wants to read also, threadB has to wait until ThreadA finishes.

The highest level is the logicl locking which is implemented using some kind of map implementation where you keep the records that are locked and notify waiting threads when locks are released. This is implemented on the update and delete method. correct ?

So, am I being correct to say that you do not need locking what so ever on the 'find()' method ?
The record currently being updated is safe from other updates or deletes thanks to the logical locking. The read will go without logical locking since the physical locking will make sure the read does not occur while the write (due to the update) is in progress...



Now, I also thought about this. The problem I found by doing this is the loss of performance when many threads are using the database. It allready begins with multiple reads: When threadA is reading, threadB needs to wait until threadA finishes (and hereby releases the lock) . This, while reading could go simultanously without any problems.
Other (less important, but still) problems are with updating. When ThreadA is updating record 1, threadB is unable to read record 2....

Am I seeing this wrong or .... ?

Thanks.
 
Matt Sheehan.
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Koen Serneels wrote:
Now, I also thought about this. The problem I found by doing this is the loss of performance when many threads are using the database. It allready begins with multiple reads: When threadA is reading, threadB needs to wait until threadA finishes (and hereby releases the lock) . This, while reading could go simultanously without any problems.
Other (less important, but still) problems are with updating. When ThreadA is updating record 1, threadB is unable to read record 2....


I don't think this performance issue will affect your grade, since it isn't mentioned in the specifications. However, many people have addressed this issue by reading all records into a cache at the application startup. This way reads can be done on different cache objects simultaneously and its only the update, delete, and create that require the lock on the file.

Matt
 
Jim Janssens
Ranch Hand
Posts: 210
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, that was my initial idea. Creating a cache.

But after giving it some thoughts I realize that implementing a good cache is not something you can do overnight. The result must also be that the Performance is better then using the read/write locks.

Some items the cache must be able to address:

- If you cache the whole file, what will happen if the files ends up with like 100.000 records ?

- If you do not cache the file at once, how are you going to choose which records to cache and which not to cache ? To be a help for the performance you have to use some algorithm.
 
Matt Sheehan.
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Koen Serneels wrote:
If you cache the whole file, what will happen if the files ends up with like 100.000 records ?

Thats why I didn't cache. The application's description in my specifications indicated that the db file would be much larger than the test file attached with the assignment. I think a lot of people do this, though, and simply note their assumption of a small file in their choices writeup.

Koen Serneels wrote:
If you do not cache the file at once, how are you going to choose which records to cache and which not to cache ? To be a help for the performance you have to use some algorithm.

I think this would be a lot of work and probably wouldn't add much to your score in the end.

Matt
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic