Here's what I came up with in respect to locking.
[ Please see
this thread for a more complete locking scheme that I finally settled on.]
(By the way, whenever I wrote HashSet, I meant HashMap.)
a) Synchronize the HashSet. (threads may wait on that.)
b) Check for record being locked in it. If yes, wait() (lock on HashSet
released.)
c) When the record is unlocked, lock it again, this time by different Data object using the calling
thread (i.e. client) lockCookie value. When checking, Data object acquires lock on HashSet automatically. Release lock on HashSet.
d) Modify the database file. Here I must guarantee that a record is unlocked only after database file is modified.
e) Synchronize the HashSet. Unlock the record I locked. Release the lock on the HashSet.
So in order to accomplish database access safely, three locks are in play:
lock 1 is the lock on the Data object.
lock 2 is the lock on the HashSet.
lock 3 is the lock put in the HashSet. This lock is purely logical: no lock is granted in the sense the synchronized keyword grants it. But this lock is accomplished by putting a key/value pair in the HashSet (record number or nubmer of bytes offset to the record, and lockCookie as the value) so that other threads, checking upon the presence of this record number, would abstain from modifying the record in the database.
That's basically what I came up with in regard to locking.
Does it look like it could work?
[ July 30, 2004: Message edited by: Anton Golovin ]