*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes URLyBird - Locking Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "URLyBird - Locking "Catch 22"" Watch "URLyBird - Locking "Catch 22"" New topic
Author

URLyBird - Locking "Catch 22"

Miles Toliver
Greenhorn

Joined: Dec 07, 2005
Posts: 12
Hello all,

I have a question/observation about the locking mechanism for my URLyBird assignment that I would like to get some of your opinions on. At this point, I have made two assumptions for my design that I think are common to many of the designs for others SCJD projects.

1) A record lock is not required for records reads. I don't mean that one client will be allowed to read a record while another client is updating the same record, but a client will not need to obtain a logical lock from the "Lock Manager" to read a record. This will help improve concurrency but will allow dirty reads. However, I think there is an overall consensus that dirty reads are okay for this project.

2) There will be no dynamic notification process to update all connected client after a record is updates. In other words, in the records displayed on a client's GUI are "stale" they will not know until they attempt to update (i.e. book) a record and receive some sort of ModifiedRecordException (or something similar).

Given these assumptions (which I think many others have made) we can draw some conclusions. First, the only time a logical lock is granted is when a client is going to update a record. Second, any client that attempts to update a record based on data that is not the latest, persistent data for that record will not be able to successfully complete there update (they will first have to reread or at least acknowledge the updated data).

To make a long story short (too late , here is my question. When attempting to obtain a logical lock, we are supposed to block if that record is currently locked by another client. What is the point of this? If the client that currently holds the lock is presumably updating the record, then the client waiting for the lock will not be able to complete their update once the lock is available (because the data will not be different). In other words, if the lock is not avaiable, the only result for the client requesting the lock will be the ModifiedRecordException mentioned earlier. What is the point of blocking for the lock to become available just to get some sort of exceptional condition.

I realize this question is somewhat theoretical since the specification list waiting for an available lock as a "must" requirement. I was just interested in getting your thoughts on this and see if I am missing something?
Mark Smyth
Ranch Hand

Joined: Feb 04, 2004
Posts: 288
Originally posted by Miles Toliver:
Hello all,

I have a question/observation about the locking mechanism for my URLyBird assignment that I would like to get some of your opinions on. At this point, I have made two assumptions for my design that I think are common to many of the designs for others SCJD projects.

1) A record lock is not required for records reads. I don't mean that one client will be allowed to read a record while another client is updating the same record, but a client will not need to obtain a logical lock from the "Lock Manager" to read a record. This will help improve concurrency but will allow dirty reads. However, I think there is an overall consensus that dirty reads are okay for this project.

2) There will be no dynamic notification process to update all connected client after a record is updates. In other words, in the records displayed on a client's GUI are "stale" they will not know until they attempt to update (i.e. book) a record and receive some sort of ModifiedRecordException (or something similar).

Given these assumptions (which I think many others have made) we can draw some conclusions. First, the only time a logical lock is granted is when a client is going to update a record. Second, any client that attempts to update a record based on data that is not the latest, persistent data for that record will not be able to successfully complete there update (they will first have to reread or at least acknowledge the updated data).

To make a long story short (too late , here is my question. When attempting to obtain a logical lock, we are supposed to block if that record is currently locked by another client. What is the point of this? If the client that currently holds the lock is presumably updating the record, then the client waiting for the lock will not be able to complete their update once the lock is available (because the data will not be different). In other words, if the lock is not avaiable, the only result for the client requesting the lock will be the ModifiedRecordException mentioned earlier. What is the point of blocking for the lock to become available just to get some sort of exceptional condition.

I realize this question is somewhat theoretical since the specification list waiting for an available lock as a "must" requirement. I was just interested in getting your thoughts on this and see if I am missing something?


I don't think that there is any need to make allowances for updates on stale information. It is best to let an update happen regardless of how old the data is, anything else is far beyong the scope of the project.

The db class is pretty stupid, all it can do is read and write the data it is told to by clients and has no idea of the meaning of the data in a record.

How could it possibly be able to tell whether a client calling its update method read a record before the last update or not, do you really want to somehow store every read and update for each client?

I think simplicity is your best friend here,
Mark


SCJP<br />SCJD
Miles Toliver
Greenhorn

Joined: Dec 07, 2005
Posts: 12
Mark,

Thanks for the reply. You make some very good points.

For starters, I definitely agree that the DB interface class provided is not a very good interface and is not how I would have designed it. For this reason, I am planning to have a URLyBirdServer class that resides on the server side and is a go-between class for the GUI and the DB class. The client GUI would invoke methods in this class such as book(), which would get the logical lock, update the record, and unlock it. Client only makes a single remote call (hence the thin client part). It would be relatively easy and straightforward to have logic in this class to detect whether the update to be made is coming from stale data or not.

I am not sure I totally agree that updates should be made regardless of the state of the data. For the URLyBird project, the only "update" currently possible from the limited GUI would be booking an empty room. Surely an update cannot go through to book a room that has since been booked by another client (hence overwriting the original, and true, booking).

Thanks for the feeback.

Miles
Mark Smyth
Ranch Hand

Joined: Feb 04, 2004
Posts: 288
Originally posted by Miles Toliver:
Mark,

Thanks for the reply. You make some very good points.

For starters, I definitely agree that the DB interface class provided is not a very good interface and is not how I would have designed it. For this reason, I am planning to have a URLyBirdServer class that resides on the server side and is a go-between class for the GUI and the DB class. The client GUI would invoke methods in this class such as book(), which would get the logical lock, update the record, and unlock it. Client only makes a single remote call (hence the thin client part). It would be relatively easy and straightforward to have logic in this class to detect whether the update to be made is coming from stale data or not.

I am not sure I totally agree that updates should be made regardless of the state of the data. For the URLyBird project, the only "update" currently possible from the limited GUI would be booking an empty room. Surely an update cannot go through to book a room that has since been booked by another client (hence overwriting the original, and true, booking).

Thanks for the feeback.

Miles


Sounds like a good design, similar to what I am doing myself. It is true that room should not be bookable if it has already been booked, however the data class does not know that what the string at recordData[OWNER_INDEX] means, so this logic cannot go there. The logic for preventing a room being double booked will reside in your book() method and not in the update method of data.

Mark.
Miles Toliver
Greenhorn

Joined: Dec 07, 2005
Posts: 12
Agreed....brings me back to my original observation: what is the point of blocking in the lock method? (aside from the fact that we have to do it as a project requirement). Not trying to be difficult, but rather I want to make sure I am not missing anything.
Mike Ngo
Ranch Hand

Joined: Oct 16, 2006
Posts: 89

Agreed....brings me back to my original observation: what is the point of blocking in the lock method? (aside from the fact that we have to do it as a project requirement). Not trying to be difficult, but rather I want to make sure I am not missing anythin


without blocking your client threads won't know if they step on each other.

Assume you want to check to make sure that the record is still available, the updateRecord() will be something like this:



You could have 2 threads. Thread #1 at step (2) and see the record is
available and is about to execute step (3) but it was putting into the waiting state. Thread #2 runs and gets past step (1) because there is no blocking. It checks and the record is avail. so it update the record and it thinks everything is ok. Thread #1 became runnable again and finish up its work and overwrites data from Thread#2.
Miles Toliver
Greenhorn

Joined: Dec 07, 2005
Posts: 12
Thanks for the post Mike.

Based on my assumptions stated above, the update method executes on the server and would have to be synchronized so that there would be no issues with Java's thread scheduling.

If we were to ignore the logical locking, the method would resemble something like this:

public synchronized void update(int recNo, String[] data)
{
if(recordHasBeenModified(recNo) == true)
throw new ModificationException();
else
//do update

}

Since only on thread can perform an update at a time there should not be any issues with threads stepping on one another, even without logical locking.

I don't intend to start a big debate. My thought is that the logical locking is required in the event that a client GUI needs to reserve a record for some period of time while making updates (likely more significant updates than just booking the room). If a client's interaction were to span more than 1 remote call, logical locking is a must. However, as the project is currently specified, the only updating method would be assigning a customer ID to an existing record. This seems like a method to have run completely on the server with one remote call to an server method called bookRoom() that does the locking, updating, and unlocking. Given this all runs on the server, I don't think logical locking is strictly necessary.

However, in the end we all know that "must" means "must".
[ November 17, 2006: Message edited by: Miles Toliver ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: URLyBird - Locking "Catch 22"
 
Similar Threads
NX: URLyBird Database Record Number Question
URLybird
URLyBird - Locking and Data class
URLyBird Locking
NX: createRecord(String [ ]) in URLyBird