Hello all -- I've just begun the SCJD, and this is my first post. My assignment is the Bodgitt / Scarper one.
I found Sakke Wiik's post from last week very interesting, because I have likewise been assuming that the locking strategy suggested in the DBMain interface is a high level kind of lock, not a low level one. In other words:
A CSR selects a contractor to book and hits, say, a 'book' button. At this point, the GUI executes isLocked() on the database. If true, inform the CSR that another CSR is editing this entry. If not locked, test to see if the record is still unbooked. If not, inform the CSR. If the record is not locked and not booked, lock it, and wait for the CSR to type in the client's ID and submit -- which he may now do at his leisure, knowing nobody else will be able to snag the contractor while the CSR is talking to the client. Whether the CSR books or cancels (timeouts are not handled well in this scenario) -- the record is finally unlocked for other CSR's to eye. The primary reason for this assumption is that, as this thread has already discussed at great length, it's crazy to export something as vital as record locking over something as inherently fragile as a network connection.
The second reason -- and please correct me if I'm wrong -- is that as far as I can tell, DBMain's locking mechanism simply sucks for low-level locking -- the comments specifically state that locking is only meant to prevent
writing by different clients. But what about a thread that's mid-read when another thread comes along and rewrites the record?
This makes no sense to me. I would synchronize -any- operation, read or write, for a given record. If you want to be a bit fancier, allow concurrent reads but no writing while reading and no reading while writing.
Andrew's response to Sakke's post:
Originally posted by Andrew Monkhouse:
Your concept is interesting. However do you have a requirement for the lock() method to block until the lock is granted? Usually there is some statement similar to "If the specified record is already locked by a different client, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked". If you do have such a statement, then client 2 will not get notification that the record is currently locked.
That being the case, if client 1 locks the record and then goes out to lunch, client 2 will be blocked until client 1 comes back.
The problem is that locking isn't just for setting the client ID. You might want to lock a record to delete it. Or (although it is not currently required) you might want to lock a record so you can remove an invalid client booking. So the lock method cannot really care about whether the record has already been booked or not. Plus, depending on your lock signature, you might not be able to indicate that the record has been updated.
Well, The requirement that lock() blocks until the lock is granted is an emergency specification only: my interface contains a boolean isLocked(), which is what the GUI ought to be using.
The time-out problem, however, is admittedly severe. I still prefer this interpretation -- I'd rather have flaky high level locking in the GUI than server-side data corruption!
I suspect I'm missing something obvious, and would love to have it pointed out to me.
Janus