I was just reviewing my choices.txt and I was looking at my reason given for synchronizing the create method.
I say the following:
The requirements state that the create method: "Creates a new record in the database (possibly reusing a deleted entry)...." So if possible a deleted record should be reused if one exists. The need for synchronization here is best explained using an example Say we have two clients accessing a remote db. ClientA finds that record 2 is deleted and so concludes that they should create their new record in place of this. ClientA's thread loses the CPU and ClientB's thread gains the CPU. ClientB deletes record 1. According to the requirements ClientA should now be creating the new record in place of record 1 and not record 2. To prevent this I synchronized the create method.
Looking at it now I'm no longer convinced of the wisdom of synching the whole method. In all other methods that use the RAF I just synch access to that. Am I right in saying that synching create is still not stopping someone deleting record 1 and therefore my create still not using the first deleted record ?
If you don't synch the method you could in theory get two requests for writing a new record resolving to write to the same position in the file (either the same previously deleted entry or resolving the same EOF position and moving to that).
So you might get: (T1 and T2 are threads of execution) T1: enter create T2: enter create T2: resolve position 1340 T1: resolve position 1340 T1: write record T2: write record
Oops, T2 just overwrote the new record created by T1. Not nice.
There might be locking strategies that get around this, but why make things overly complicated? It's not as if it's a very long running method, so the other thread will only be waiting for a few milliseconds (unless you have your database on a floppy or other very slow medium in which case it might be a bit longer).
You could do the following:
createMethod begin create write buffer synch on file locate position to write write buffer to file release synch lock exit method
Might be a bit cleaner. Note I've not tested this, what would happen to the write buffer of T1 if T2 entered the method while T1 was in the synchronised block but hadn't yet written the buffer to file completely?
You might end up with a corrupted buffer, and thus a corrupted database.