It's not a secret anymore!
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes No need to lock before modify or delete record. 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 "No need to lock before modify or delete record." Watch "No need to lock before modify or delete record." New topic

No need to lock before modify or delete record.

morph wang
Ranch Hand

Joined: Aug 23, 2001
Posts: 38
I did not see any necessary to lock record in modify() or delete() method itself. I think the lock()/unlock() are only useful for book seats method.
And, I don't think it's a must to judge if the client when unlock a record, to do that, we must alter the signature of lock()/unlock() method, that's not good for this assignment.
any one can pull me out off ignorance ?
[This message has been edited by morph wang (edited August 28, 2001).]

Michael Ernest
High Plains Drifter

Joined: Oct 25, 2000
Posts: 7292

Hi Morph -
To resolve this question, consider what happens when any two clients attempt to use the same record at one time.
Let's say you are in the middle of modifying record 5, and I decide to modify it as well a few milliseconds later. If there's no code to make the act of modifying that record an atomic operation, there might be several permutations for the result. Since this must be a multi-threaded system, and the order in which threads are selected to run is not determined from our point of view, it may not be clear what result we get. For example, let's say we are modifying the contact information. One scenario in unsynchronized code might be that your changes (first and last name) get saved along with mine (address, city, state). If we think we've both updated the record successfully, the result is not too useful.
Deleting records without locking the table is a problem for operations that might scan all records in the table. Let's say I decide to loop through all 50 records and perform some table-wide operation. I get a count of 50 records and start my loop. In the meantime, you come in and delete a record. Now after I get past record 49, I'm going to have a problem, because my loop thinks there are going to be 50 records.
In short, we synchronize to protect against not the probability of misfires, but the possibility of them. Without that protection, we end up with the possibility that some cases for output are not determined by our code. That's bad on Exam code, but only because that problem is far, far worse when it finds its way into production code.
Michael Ernest, co-author of: The Complete Java 2 Certification Study Guide
[This message has been edited by Michael Ernest (edited August 25, 2001).]

Make visible what, without you, might perhaps never have been seen.
- Robert Bresson
Paul Anilprem
Enthuware Software Support
Ranch Hand

Joined: Sep 23, 2000
Posts: 3635
"modifying a record" and "booking a seat" are operations defined at different abstract level.
Modifing a record is an activity of the data layer which does not know anything about the business. Now, as your data layer is file based, any modifications that you might want to do to the file must happen one by one. Obviously, there is only one file pointer and if you use concurrently it in multiple threads, it'll surely screw up the file. And for this reason all the actual file modification methods ( add, delete, modify) are synchronized. The concept of record locking does not come into picture at this point of time. For the file pointer there is no record, just one big data file. You cannot actually "lock" a record. You have to lock the whole file. That's what making all such methods synchronized does. Locks the file.
This is necessary for the consistancy of the file.

On the other hand, booking a seat is a business rule. The objective is you cannot book more no. of seats than seats available. Consider this: 2 people are viewing the flight info. They see that there is one seat available from A to B. Both try to book the seat. Obviously, someone will be the first one to book the seat, thereby modifying the record. The other one's modify call will come next and that makes the available seats to -1. Notice, that this is perfectly ok with the data layer as the file itself is not currupt! but the logically it is screwed up! (because available seats is -1). To prevent this you have to build a notion of "record" lock on the top of file lock. You cannot achieve it using synchronized on the modify() etc methods. synchronized is only useful for the consistancy of the file. You need something extra for the consistancy of the business. This extra is lock()/unlock() methods.
You've to implement them such a way that while booking a seat clients should "feel" that the whole file is not locked up but just that record. Although, when you actually modify the file, whole file has to be locked up.

SCJP2 Resources, Free Question A Day, Mock Exam Results and More!
Get Certified, Guaranteed!

Your guide to SCJD exam!

Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
morph wang
Ranch Hand

Joined: Aug 23, 2001
Posts: 38
Thanks a lot! Michael
If there's no code to make the act of modifying that record an atomic operation...

In this assignment, there is only one SINGLE instance of data class will be present, and since modify()/delete() are
already synchronized method(synchronized on data instance), so they are all atomic operation already. AND, when one
thread is in modify()/delete() scope, there won't be any other thread in delete()/modify() scope.
Thanks a lot! Paul
"modifying a record" and "booking a seat" are operations defined at different abstract level....

Your comment really gives me a light hint! In this assignment scenario, the 'data layer' is already thread-safe( in Data
class), What we ONLY have to do is to make the 'logical layer' thread-safe, that's why it's NO need to assign a 'logical
layer' lock(record lock is logical lock, right? ) on ANY 'data layer' operation(modify()/delete() etc.).

AND, bookseat(...) is a 'logical layer' operation, so we must assign a 'logical layer' lock on it, right ?
Although it won't bring harm to make modify()/delete() method in Server class to be record-level synchronization, but it's
redudant, and should be considered WRONG in strict point of view !
Please comment back, Thanks advance!
Jon Trussler

Joined: Jul 05, 2001
Posts: 9
This is a little off the topic but I think it raises some important issues with record locking. I implemented a record locking system that keeps track of clientid by giving each remote user their own server side connection object. Now, in a well behaved system, each client will always perform, say a modify operation, by the sequence lock, read, modify, write, unlock. How well-behaved should we trust our data clients to be? If we track our clients, we can always make sure the record is locked by a certain connection before we make our database calls. In our remote implementation, we can obviously delegate much of the work to our methods in the Data class. So should we have additional checks around our delegation of the modify or other database functions to handle record locking if the client is not well behaved? This will definitely cause some overhead but will create a more stable and secure implementation. How does everyone weigh this trade-off.
Any thoughts or suggestions?
morph wang
Ranch Hand

Joined: Aug 23, 2001
Posts: 38
Hi, Jon, you keeps track of clientID, did you alter the signature of any mothod in Data class? if do, is it illegal for this assignment? What do u mean that 'server side connection object'? r u using RMI or socket?
Do u think it will bring any more stability in following code if uncomment the commented code?(I don't think so!)
public void modify(DataInfo newData)throws ..{
// int recNum = newData.getRecordNumber();
// lock(recNum);
// unlock(recNum);

In my personal opinion: the server side is only reponsible for protecting the data-layer integration(say the consistence of db.db file, protecting by synchronization on Data instance, the original already implemented it!) rather than the logical layer integration(for example, available seats is filled with -1, this failure will be avoid by synchronization on record, should be implemented ourself in client side).
According to this viewpoint, my implementation of client has a book() method which do lock->read->modify->unlock, any other method(modify(), delete() etc...) will just delegate saming calling to remote server. And in server side, just delegate method calling coming from client directly to Data instance. That's it!
What's ur opinion on my implementation?
[This message has been edited by morph wang (edited August 28, 2001).]
Jon Trussler

Joined: Jul 05, 2001
Posts: 9
hi morph,
yes i do keep track of the client that places each lock without modifying any method signatures. i also use RMI. the Remote Database is actually the server connection object. each client gets its own copy. if you take a look at the the "Contradictory requirements" thread you will get a better insight into how to accomplish this. however, by searching through the forum, it seems that a minority of the people actually take this trail.
uncommenting the locking code above will only be useful for clients that are not well-behaved but will put a little burden upon well-behaved clients. obviously we cannot delegate all the methods to the data class (lock/unlock). but do you think that if a networked client wants to write to a record but hasn't got a lock, you should acquire a temporary lock behind the scenes? I haven't made up my mind on situations such as this. I don't know that the server should assume that clients aways act as we expect them to.
I agree. Here's the link:
subject: No need to lock before modify or delete record.
It's not a secret anymore!