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

My Locking Strategy...

 
Millicent Bare
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the URLyBird project, I don't think the lock methods specified in the DBMain interface are required to make the application thread-safe. And since my previous post ("Why are lock methods required?") was basically ignored, I'd like to get everyone's feedback on my strategy.

Here we go!

#1: I assume Sun's examiners have some test setup for the specified DBMain interface, so that I should completely implement the interface as they expect or I'll get an automatic failure. However, the locking methods are not needed for the application to work correctly, so I'm not going to call them within my application but will implement them. Is this a correct assumption and follow-up on my part?

#2: My read(), update(), delete(), and create() methods all will be synchronized methods, because otherwise the file pointer could get moved around by a second thread if the first thread lost its timeslice at a bad time. THEREFORE, these four methods are all atomic and cannot interfere with each other. If these methods are to be atomic, I cannot let them call wait() when isLocked() == true, so I'm just not going to call the lock methods.

#3: There's no way to prevent the following scenario, so instead I'll react to it instead of trying to prevent it. The scenario is that clientA could "find" available rooms, then clientB could "find" some of the same rooms. Then clientA might book a room on his list that is still present on clientB's list. ClientB may then attempt to book that same room. That's a conflict that can't be prevented. Obviously I can just generate an error message to clientB instead. No locking is needed here.

#3a: An alternative that I'm not supporting is to have clientB's list get updated automagically when clientA books a room affecting clientB's list. But this still leaves a race condition between clientB's booking and his list getting updated, and there's no requirement to make it so complicated.

Incidental point: My application only needs to call update() and find(). That's because there's no requirement to support cancelling a reservation.


Thanks in advance,
Misty
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Misty,
Originally posted by Millicent Bare:
#3: There's no way to prevent the following scenario, so instead I'll react to it instead of trying to prevent it. The scenario is that clientA could "find" available rooms, then clientB could "find" some of the same rooms. Then clientA might book a room on his list that is still present on clientB's list. ClientB may then attempt to book that same room. That's a conflict that can't be prevented. Obviously I can just generate an error message to clientB instead. No locking is needed here.
Under what conditions would you generate an error / what sort of error would you generate?

My reading of the instructions suggest that there is nothing whatsoever in the Data class that is specific to a given assignment. It is specific to a particular database schema, but as long as the same schema is used, the Data class could be used for hotel rooms, or client address details, or a join table between the two - or any one of a number of other purposes.

Given that, I believe it would be a mistake to write the Data class such that the update method can only ever update a single field - it must be able to update any field within the table, (or even multiple fields simultaneously).

If you have to allow for any field to be modified, then you cannot write business logic that might generate an error if a specific field is updated (or even generate errors if a field is updated if it is not blank).

Let's reconsider how we might handle this if we allow locking:So now we were able to handle the error handling from wherever you choose to put business logic (whether that is in the client GUI, or whether it is in your server). The main point is that there is no business logic in the Data class.

By the way - this is mentioned in the JavaRanch SCJD FAQ

Regards, Andrew
 
Markus He. Jung
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
(URLyBird 1.3.2)
I have an different approach. I explain my whole strategy, i hope it will help you with your locking issues.

I'm using RMI and therefore i have an exposed Business Object (RoomManger) these Object enables an RMI client to call the methos listAll, book, search. These are the major functionalities.

The are no locking issues at the client side. The locking issues are all taken at the server side within RoomManager, if ClientA wants to book a record. The book method first aquires a lock on the record. I'm using ReentrantReadWriteLock since this is part of Java 1.5. The locks are managed in a big collection where a lock for each record exists. (Managed in the DBMain implementation).

Now lets continue. The book method locks the record. Then it does an update an then it releases the lock. A lock is only be held for one single method call from the client-side view.

This makes your life very simple, since there can be no deadlocks, and no lost locks. Locks can only be lost if the server crashes and if this happens the server has to be restarted and everthing works fine again.

Therefore in the implementation of DBMain the update, create or find method do not have do deal with locking. This must be done one layer up, by the caller of this DBMain implementation. Thats the way i understand the requirements, otherwise the lock and unlock method would not make any sense.

In my implementation it would look like this:

Client A request all Records
Server locks all Records
Server reads all Records and return them
Server unlocks all Records
Client B request all Records
Same as before ...
Client A books record 5
Client B books record 5
Call from Client A is processed a little bit faster and it first receives the thread-safe lock of record 5
Call from Client B reaches the critical section, but the lock is already held by Client A
Client B waites ...

Client A continues
The book method checks if the room is not booked by someone else.
Client A updates the record and unlock the record and returns.
Client B is now available to continue
The book method checks if the room is not booked by someone else.
The check failes and an error is returned to the client.
Now it does make sense that in the case of an error, the Client refreshes all displaying records --> then Client B sees that Client A has already booked the record.

The data of the JTable on the clientside could be dated out, but if it is not everthing works fine, it's a little optimistic strategy. If two clients try to book at the same time one will fail.

I hope that has helped you.
 
mario aixel rodriguezjaen
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
is it okay to use the BlockingQueue object from 1.5 ? It eases the development of the producer-consumer pattern assuring that the operations of adding and taking objects from the queue are thread safe.
 
Lucy Hummel
Ranch Hand
Posts: 232
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that using BlockingQueue is quite okay.
 
Tai Hu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Markus, I really agree with your approach and indeed I implemented my URLyBird (v1.1.1) using the similar strategy. However, I have one question about this approach. If SCJD grader used an automatic tool to test DBMain directly, can we assume that their testing method will call lock method before calling update, delete method and call unlock method afterwards? If not, since we put locking strategy into an higher level class, direct calling update, delete method will mess up the data.
 
Lucy Hummel
Ranch Hand
Posts: 232
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tai,

If sun calls delete directly, they know exactly what they want to test.

Otherwise, they will for sure check if and how we do the (un)lock, read and write.
 
Ken Boyd
Ranch Hand
Posts: 329
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In my assignment URLyBird I have lockCookie and in case they do test directly on Data class Update or unlock method it will reject it since lockcookie won't be same as they provide (manager class create random one)
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic