The DBMain interface that we "MUST" implement appears to be insufficient. It gives method signatures as follows:
public void update(int recNo, String[] data) throws RecordNotFoundException
public void lock(int recNo) throws RecordNotFoundException
public void unlock(int recNo) throws RecordNotFoundException
Along with the documentation on lock:
Locks a record so that it can only be updated or deleted by this client. If the specified record is already locked, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked.
And a supplemental requirement:
Any methods that throw RecordNotFoundException should do so if a specified record does not exist or is marked as deleted in the database file.
Adhering to these requirements leads to the following issue. If lock/unlock/update do not return anything and only throw RecordNotFoundException (and RNFE is used as it "should" be), then how do you know if your call was successful? If a client ask for a lock that is already taken, it waits for the lock to be available before completing. However, if a client attempts to unlock or update and does not own the lock, the update will not happen, but there is no sufficient way to notify the client as to what happened. There are 3 ways around this that I can see:
1) Throw a RecordNotFoundException with a message stating "failed to update - not owner of lock".
2) Throw an unchecked exception.
3) Check to see if your update was successful by doing a read and comparing with what you just tried to update to.
All three of these have drawbacks:
1) RNFE has the stated purpose of being thrown when the "record does not exist or is marked as deleted", and the only way to know that this is what really happened would be to catch RNFE and check the message for this type of failure (HUGE HACK).
2) Unchecked exceptions have the stated purpose of "represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way" (
http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html) which is clearly not the case here.
3) Seems silly to have to check if your update actually went through by checking to see if the data is what you just tried to set it to.
Am I missing something here? Does anyone else have any ideas? As far as my client implementation goes, i would have the client remember if it was able to obtain the lock (by calling lock and waiting for it to return), but the fact that we have to implement this interface leads me to believe that other applications (such as the reporting applications mentioned in the overview) might need access to the data as specified. Any input/discussion would be greatly appreciated.