1. Point 4 � would this be the correct way to do this i.e. each Data object has its own RandomAccessFile? I am not sure about the writing and reading to these files � will the reads and writes for a record be atomic? Anytime I want to write or read a record I call the relevant method in DataHelper � is this okay? I see some people are using filechannels � are these better (I have never used them and have limited experience even in file I/O)?
2. Are the mechanisms in points 5 and 6 okay?
1. Point 4 – would this be the correct way to do this i.e. each Data object has its own RandomAccessFile? I am not sure about the writing and reading to these files – will the reads and writes for a record be atomic?
Anytime I want to write or read a record I call the relevant method in DataHelper – is this okay? I see some people are using filechannels – are these better (I have never used them and have limited experience even in file I/O)?
. After having a very quick look at the thread on exceptions (I mean 'very quick' as it will take me a long time to work through this thread!) I notice that in your lock method you are posted (6th of September) you do
Before you get into your while loop within, the synchronization block, you may want to check if the record is already locked by this client?
....stuff goes here
Am I wrong in saying that neither of these could (!!) take place if the protocol a client/thread is using follows the lock - update - unlock sequence?
It would help me immensely to zero-in on the problem if you copy the sections of the text that are causing the confusion and state them here within quotes
1. int deletedRecord in the data class.
2. Initialize it to zero in the constructor for the data class
3. set it to the deleted record's value within the delete method
4. check in the unlock method if the deletedRecord value is equal to the passed record number? if it is then do not call the private validateRecord method but reset the deletedRecord value to zero since you acknowledge that this is the record being unlocked and no RecordNotFoundException should be thrown.
Implicit in your reasoning above is the understanding that you expect the sequence lock-update-unlock to be atomic! It isn't, it all depends on threads slicing in and out of the method calls as the scheduler decides.
It is not that each Data object has its own RandomAccessFile but rather each Data object has its own HANDLE to the same RandomAccessFile - two entirely different things. Since each Data object reads, writes, updates, and deletes the same physical file, you are synchronizing on your mutator methods given in the DBMain interface. Does it make sense?
Maybe I�m being a bit too general or vague here, I�m not sure. Essentially I need to know how to set up the data access layer to incorporate using a randonAccessFile when there are many clients, but I�m confused as to how to implement this.
I think there is a flow, when should I close RAF?
Where exactly did you create your randomAccessFile? I am confused as to how to implement this � maybe you could help me here.
Regarding the "lock-delete-unlock" sequence throwing an exception. Your methods do not require you to throw an exception if the user calls unlock() on a record that is not locked. Therefore you could unlock the record as the last step in your deletion. The call to unlock would therefore do nothing.
Personally I agree that unlock() should not throw RecordNotFoundException. Since the lock had been granted, there should be no reason for the unlock not to work. And it will cause an exception to be thrown every time if you use the lock-delete-unlock sequence (does this mean that delete does an implicit unlock? or you just document this issue?). But my feelings are irelevant - Sun have told us what they want.
You mentioned that most of Data's public methods are synchronized, but later you said that you have one instance of Data per connected client. So the synchronization does nothing for you, and causes a performce hit.
Any methods that throw RecordNotFoundException should do so if a specified record does not exist or is marked as deleted in the database file.
It isn’t an issue really with the project as the GUI does not allow you to deleted a record. Therefore it would probably just need to be documented in the choices.txt document.
Whats the advantage/disadvantage of having a unique data instance for each client, against single data instance.
[Vlad: You open/close FileChannel for read/write. (idea of Max, but I don't like it).]
Vlad can you pls explain this option?
Now when you call getRAF() method on the DataSchema instance, e.g., dbSchema.getRAF(), you will receive the same handle on the RAF file for ALL Data instances.
Another question which I have is as follows. I made all the public methods in my Data class synchronized e.g.
I hope you are not offended when I say "stop and read-up".
Anyway, you have to synchronize your getInstance method
the second parameter "rw" is ok or it's better to use "rws"?
Does it mean the one and only RAF-File will be closed when the Server shuts down, like Vlad suggested?
I have a DataHelper class which has the two static methods below included (this approach was advocated in a few threads � I think you may have used this approach as well). The readFixedString method is called from the singleton DataSchema class and the Data class. The writeFixedString method is called from the Data class. My question is, should these methods be syschronized?
Thanks for your help