This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I have created 2 different threads to test update in file. My threads (both instances of different classes) make objects of DAO class. both update the file in a loop. One from 3-11, other from 15-24. Strange thing is when this file is run almost 20 times. The file gets corrupted. record #24 is not written correctly. OS is windows XP. NetBeans IDE 7.2. Is it a locking problem or something with the OS. Have tried a CleanExit too. same result.
First of all: a warm welcome to the JavaRanch! Let's have a to begin with
It's hard for us to indicate the problem with such little information. Maybe you have to give us a high level overview of your class hierarchy & give us a bit more detail (e.g. is your Dao class implemented as a singleton?). That might help to narrow the problem down.
Thanks for the help.
The DAO class has static DataFileAccess and ReservationManager objects. I am using an ArrayList cache that holds all the records. It gets initiated the first time DAO object is made. I think the problem is with locking as whenever control changes to another thread, there are chances of corruption of file. In DataFileAccess, first the cache is updated in a reentrantLock.writeLock() and unlock() block. Then after closing this block physical database is updated in a synchonized(database) block. also there is a lot of conversions going on between String and byte in non-synchronized utility methods. I think I have to check by only updating the physical file leaving the cache alone.
Things to investigate:
- How many instances of the DataFileAccess class do you create?
- How many database-objects do you have? Because if each thread has its own copy the synchronized block is useless.
- You have to put both adjusting file pointer and writing to the file into the synchronized block.
- Does your update-method always create the good record structure or does it sometimes mess up?
Rehan Zahoor wrote:I created 4 threads and performed more database update/create operations and data was corrupting more often. The delete bits in the start of the record get smashed.
Hello Rehan buddy,
Make sure your file pointer points to the right position. If your data file (provided by Oracle) starts at location 70, then use RandomFileAccess's seek method and seek from location 70.
Do you do this?
Do you read Terry and Andrew Monkhouse's SCJD study guide published by Apress?
It is a good reference.
My db package is quite similar in design to Monkhouse's db package. If my threads all use the same Data class(similar to DvdDatabase class of Monkhouse) object then the database file is not corrupt. While if they all create their own Data objects, then file is corrupted. Is it the right behavior?
Rehan Zahoor wrote:My db package is quite similar in design to Monkhouse's db package. If my threads all use the same Data class(similar to DvdDatabase class of Monkhouse) object then the database file is not corrupt. While if they all create their own Data objects, then file is corrupted. Is it the right behavior?
As my good buddy Roel mentioned, if each thread has its own database object then synchronization block is useless.
Not sure from your post if your Data class is singleton or not but ALL threads need to point to the SAME Data class.
Also to avoid messing up your db file, I check the magic cookie value after each update/insert/delete to ensure the integrity of the file.
The problem is with my cache initialization. When I add creation of Data Object as first line of my main method, Data corruption is avoided. Otherwise there is some kind of Race condition among test threads that is causing data corruption. . Thanks a lot for the help.
Now my worry is how to initialize cache. Its only
I have put it in a synchronized block. If Data class object is created in the run() method of TestThread it causes corruption of database file. Works fine if creation of Data object is in the constructor of TestThread class instead of in the run() method. Do you think that is enough. I think that should be ok. Creating Data class object in the constructor of user classes would ensure database file safety and integrity. and resource initialization should be in the constructor any way.
Hello Rehan buddy,
When you mentioned "corruption of database file", do you mean the data is written in a wrong position in the file?
Check with your schema provided by Oracle.
I got a different instruction.html from yours. What I have is 2 bytes for valid flag, 64 bytes for name, 64 bytes for location , 64 bytes for specialty and etc.
So, when you write data to your database file, make sure you reserve 2 bytes as a valid flag, 64 bytes for name and etc. This is just an example. I am sure your schema is different from mine.