aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes locking and the find method. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "locking and the find method." Watch "locking and the find method." New topic
Author

locking and the find method.

Matthew Arnold
Greenhorn

Joined: Jun 09, 2005
Posts: 3
I'm doing the B&S project. My current implementation of the Data interface has each method open a file stream and close it upon completion. The problem I'm having is the following.

Client A locks a record for updating. Client B starts a search operation. The search operation could possibly bring back data that has not been updated.

One solution is to not allow the search operation to run only if no records are locked and not allow any records to be updated/created during a search operation. Does this sound like it makes sense or do I need to change the structure of how I'm accessing the file?

Thanks

M


MA<br />SCJP 1.4, 1.5
Lara McCarver
Ranch Hand

Joined: Dec 09, 2003
Posts: 118
Just restating what I think you said... you said that your Search operation is going to lock the entire database. As a practical matter, what this would mean for Search is you would have to hold off on doing any more individual record locking until all the current locks are unlocked, then you would do your search, then you could allow all the queued-up lock requests to go through. To me, this sounds like it is more complicated than it has to be.

What I am doing is to implement my find() as a series of read() operations. The read() method locks its record before reading it, and unlocks it when finished, therefore every record that the find() method examines is up-to-date. You do have to have a way to know what the maximum record number in the database is, to make this workable, but that is easy. As long as you always lock the records in a consistent order (i.e. you start by locking record 0, then you lock record 1, etc.), you don't have to worry about deadlock either.

I think this method is a lot easier, but I should point out that my instructions do not require that I provide a method to lock the entire database. If you instructions do require that, then I guess it's pretty easy to take advantage of that functionality
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11509
    
  95

Hi Mathew,

If you did go down this path, I would strongly recommend you look at the ReadWriteLock class of JDK 5. You still risk reducing concurrency, however read locks will give you better concurrency than generic locks.

However I suspect that you are going to make this far more complicated than it has to be.

For a start, your find() method probably only returns the record numbers of the matching records. So there is still a risk that the records will have been changed between calling find() and calling read() for each of the found records.

Once you have retrieved the records there is the possibility that they may be changed sometime between you retrieved them and the user tries to book a record. So you would have to add some sort of Observer pattern to your server such that the clients can get automatic updates anytime a record is modified. This then causes a major tradeoff: do you notify every client of every change (even if they haven't retrived the record that was just changed) - potentially generating a large ammount of unnecessary network traffic; or do you track which clients are interested in which records (potentially large memory requirements if you have a large number of connected clients).

I think it is worth noting that major reservations systems (sort of airline standard) do not bother with trying to ensure a perfectly accurate view of the records - they give a snapshot of each record that was correct at the time the record was queried (which can lead to some strange situations where codeshared flights can appear to have different numbers of seats available if the query happened to coincide with a booking).

Personally I think Lara's solution is much simpler, and still meets the requirements.

Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Matthew Arnold
Greenhorn

Joined: Jun 09, 2005
Posts: 3
Thanks Lara and Andrew. Let me ask another question. I've been considering multiple file pointers vs one file pointer. I don't think Lara's way of implementing the find method would work with multiple file pointers. If two clients were running the find method, client a could lock a record for reading and break out. Client b could come across this record and skip to the next one, which would not give an accurate view of the data in the database. I'm considering synchronizing the data access methods in the which would allow for only one file pointer(the way my design is), however, two clients could not read or read-and-write at the same time. Would this violate what they are looking for?

Thanks.

M
Lara McCarver
Ranch Hand

Joined: Dec 09, 2003
Posts: 118
If two clients were running the find method, client a could lock a record for reading and break out. Client b could come across this record and skip to the next one, which would not give an accurate view of the data in the database.


My read method, which find() calls for each record in the database, looks like this:


Let's say that client a is doing a find() and its thread breaks while it is reading record 4. Now the thread for client b starts running, and it tries to read record 4. Since the read() operation locks the record, client b is not going to be able to proceed. It will have to wait for client a to relinquish its lock on Record 4.
Matthew Arnold
Greenhorn

Joined: Jun 09, 2005
Posts: 3
Your right Lara. I miss read what you had said. This way, as long as the lock manager is synchronized, none of the data access methods need to be synchronized.

Thanks

M
Samuel Pessorrusso
Ranch Hand

Joined: Jul 21, 2005
Posts: 164
but think in the scenario:
Every operation is done by one client:

locks the record X
updates the record X
find (criteria that matches with record X)
...
...
...
unlocks the record X

The operation "find" generates a dead lock when it is performed ( because it uses the read method that tries to lock the record 1 but the record is already lock, so the thread waits...forever...)
[ August 04, 2005: Message edited by: Samuel Pessorrusso ]
Lara McCarver
Ranch Hand

Joined: Dec 09, 2003
Posts: 118
Samuel,

In reference to your scenario:

locks the record X
updates the record X
find (criteria that matches with record X)
...
...
...
unlocks the record X


I agree with you that this scenario could cause a deadlock. So, my lock() method does a check for a possible deadlock scenario, and if it finds one, it throws a PossibleDeadlockException. My possible deadlock method is extremely simple: each client is only allowed to lock one record at a time. That's just because it does prevent deadlock, and it is possible to implement all requirements for the assignment with this simple choice. The more flexible way to check for deadlock is to keep track of all the records that each client has locked. When a client tries to lock a new record, you only allow it if the record number is higher than all the records the client currently has locked. So a client can lock records 1, 4, 5, and then record 9 without unlocking anything, but the client cannot lock record 6 and then record 5, unless record 6 has been unlocked. I didn't do this because it's more complicated and... not required. Besides, I didn't want to write all the junit tests for this more complicated method

However, even though locking records while you are doing a find operation means that you can't do your scenario, my ultimate response to you is going to be: So What? Why does the server need to support this scenario? Certainly, there is nothing in the GUI requirements that indicates that the client would ever be doing such a sequence.

Just because you have to support lock(), update() and find() in the Data object does not mean that you have to support any sequence of them. It doesn't specifically state that deadlock prevention is a requirement, but I am concerned that if deadlock is possible, I will lose points on the exam. In the book, "Java 2 Sun Certified Progammer & Developer" by Kathy Sierra & Bert Bates, in Chapter 15, in the Locking section, p. 640, they say,

Is there any possibility of a deadlock? Where two or more clients are waiting for each other's locks?


I think it is easy to explain in your update.txt that you have decided to implement deadlock prevention. As long as PossibleDeadlockException is not a checked exception (i.e. it extends RuntimeException instead of Exception), you can throw it in your Data class and still be implementing the required DBMain interface.
Samuel Pessorrusso
Ranch Hand

Joined: Jul 21, 2005
Posts: 164
I like your PossibleDeadlockException approach. I like it a lot! Thanks for opening my mind. How do you identify the client ? Thread.currentThread().getName() ?

Thanks again

Samuel
Lara McCarver
Ranch Hand

Joined: Dec 09, 2003
Posts: 118
Each client gets its own Data object, and also its own RMI server object. The Data object contains a unique integer that identifies the client. (In a future version, it would be better for the unique integer to be the client ID, but that's not part of the spec...) I felt like I was pushed into this design decision because my read, update, etc. methods don't have a cookie.
Samuel Pessorrusso
Ranch Hand

Joined: Jul 21, 2005
Posts: 164
I was reading my assignment and don't say anything about deadlock. So I'm going to document that deadlock can occurs when clients locks random records and that clients should lock records only in crescent order.
I won't prevent the deadlock because my project have already 3000 LOC and I'm cutting off anything out of assignment scope (and documenting it).
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: locking and the find method.