aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes B&S 2.2.1 howto prevent nested locking 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 "B&S 2.2.1 howto prevent nested locking" Watch "B&S 2.2.1 howto prevent nested locking" New topic
Author

B&S 2.2.1 howto prevent nested locking

Jethro Borsje
Ranch Hand

Joined: Jul 22, 2008
Posts: 100
Hi everybody,

I am currently working on my locking solution for the B&S v2.2.1 assignment.

At startup time I read all records in a Map using a RAF. When the application runs all records are read from the map. If a user adds, updates, or deletes a record this is reflected in the map, and also directly in the data file using a RAF. I am using the Map as a caching mechanism to allow for fast reading / searching of the records. Locking of the map is done using a ReadWriteLock, access to the RAF is safeguarded by synchronizing on this RAF object when performing read and write operations using this RAF.

Logical locking is done using a Map which stores both the record numbers and the associated lock cookie value. Access to this map is safeguarded using a Lock object. However, I am not sure if this is needed.

Now regarding my locking solution: I am using a Facade which makes sure that all update & delete operations are done in the following sequence:
- lockRecord
- update / delete
- unlockRecord

I am stuck with my lockRecord method (everything else is implemented), this is the problem:
The interface of Sun states that I have to throw a RecordNotFound exception from the lockRecord methods if the given record number is not found. If I want to check if the record exist (using my cache Map) I think I have to get a readLock for this map.


After this check I perform the locking:


However, I am not sure if this will work. Please consider the following case: Client A wants to update record #1, Client B wants to delete record #1.

Client A locks record #1, the lockRecord method checks if this record is present (which succeeds). After this the Client A thread is put on hold for Client B. Client B also wants to lock record #1, it also checks if it is present (which succeeds), after which it obtains the lock, deletes the record, and unlocks the record.
Now the Client A thread is resumed which locks record #1 while it is no longer there...

If I keep the map of records locked while waiting for my logical lock on record #1 I think I will be introducing possible deadlock, because it would result in nested locking:
[1] - lock the records map (read lock)
[2] - check if record exists
[3] - lock the logical locks map
[4] - check if we can get lock (if not wait until we can)
[5] - lock record #1
[6] - release lock on logical map
[7] - release lock on records map

Is there another way that I should go with respect to these locking issues?

I am sorry if this became a rather long post, however making it shorter would not give you all the needed information.

Best regards,
Jethro


SCJP, SCJD
eugen grosu
Greenhorn

Joined: May 12, 2006
Posts: 4
Hi Jethro,

I also have B&S and designed the locking part the same as you are doing.

You must insert the code that checks for contractor's existance after exiting the while loop:

long cookie = System.nanoTime();
this.locksMapLock.lock();
try {
// Wait for the record to become unlocked.
while (this.locks.containsKey(recNo)) {
try {
this.lockReleased.await();
} catch (InterruptedException e) {
logger.log(Level.INFO, "Waiting on locks map interrupted.",
e);
}
}

// Check if record exists.
try {
this.recordsLock.readLock().lock();

// Check if the given record is present.
if (!this.records.containsKey(recNo)) {
throw new RecordNotFoundException(
"There is no record with number " + recNo);
}
} finally {
this.recordsLock.readLock().unlock();
}

this.locks.put(recNo, cookie);
} finally {
this.locksMapLock.unlock();
}

I added a private method that checks for the contractor's existance, because it is called from other parts too: delete(), update()
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: B&S 2.2.1 howto prevent nested locking