How can I accomplish logical rollbacks on a database file?
I mean I have a logical lock and unlock facility, but what happens with a record half way being written to the unerlying file when suddenly this process is interrupted by an IOException ?
Having no rollback facility, the record would be left in an inconsistent state in the file.
So how did you implement this security feature?
Should I read before update? And if update fails, write that read helper record to file again?
Or what else do you suggest?
I implemented a record cache, so I never write records back to file, until the server is stopped. So that's far more critical than writing each change back to file. If server crashes after a week, all work of past week is gone. So I mentioned this in my choices.txt and a possible solution (a seperate thread writing every hour the changes to file for example). But i didn't mention anything about what to do with a hard disk failure.
Roel De Nijs wrote:
I implemented a record cache, so I never write records back to file, until the server is stopped.
I also implemented a record cache, but only for reading purposes, because my assignment mandates to write off
changes instantly. At server-startup the file is completely read into the cache. If further changes happen to the file
the cache is updated immediately as well, so subsequent searches or record-requests can be done in a consistent way.
But what should I do when some exception occurs during the writing process before the cache gets updated? There may be different information on the file than in the cache ...
Cheese, I just have big troubles with that situation.
I think it was certainly in your dreams I never heard someone mention this requirement. But you are right: mentioning it in your choices.txt will be of no harm. But you can simply not mention everything you think of, because otherwise your file will be extremely huge (mine was approx 590 lines of 80 chars). Furthermore for every problem I encountered (or thought of), like memory issues when using a cache with a db file which will keep increasing, I mentioned the problem and some possible solutions. For a hard disk failure there are little or none work arounds: what are you gonna suggest if your hard disk ran out of space for example
To be honest I don't have a clue when an IOException is actually thrown when writing or reading a file, so I don't know if it only happens on hard disk failures. For the assignment I just made the assumption (which I didn't document by the way): when I'm able to successfully read the file when I initialize my Data class (and build the record cache) I will be able to successfully write the records back to cache.
Of course I caught the IOException when writing (otherwise the program wouldn't compile ), but I didn't have a disaster recovery plan. I gave following explanation in my choices.txt about the record cache approach:
A possible drawback of this approach could be: if the writing to the file fails, everything will be lost. Although this should occur very rarely (e.g. when the disk containing the database file runs out of space) a possible solution could be: creating a seperate thread that writes the records to the file each hour.
Certainly if you are a Weichei and afraid that if you don't handle a situation it may lead to automatic failure Seriously, I was also very frightened to fail, that's why I tried to do it as perfect as I could and kept it also as simple as I could (less error-prone). If your Data class is thread-safe, the locking mechanism works and your network server does what is expected, I think it is almost impossible to fail.
I also think a structured plan will help you deal with this assignment. I started with my Data class and kept working on it until it was completely finished (with a 100% test coverage). Then I made my standalone implementation and my network implementation (of business service), also both with a 100% test coverage. Finally I dealt with my gui. And during development I kept a small file where I made some notes about things I certainly had to mention in my choices.txt, which I created when my program was completely finished.
Roel De Nijs wrote:And during development I kept a small file where I made some notes about things I certainly had to mention in my choices.txt, which I created when my program was completely finished.
That's an intelligent approach. I had to write everything in the end of the project, and it wasn't as easy as if I had made notes during the development.
In a well-defined architecture, it doesn't really matter where you start the development (it can be the view layer, business layer, etc...). For instance, if you start from the business layer (or domain layer, depending on your approach), you can still define interfaces for your DAOs / persistence layer components / repositories and use mock objects, which will act as if these interfaces were already implemented, so you can focus on the business logic and not bother with infrastructure details for a while. I myself started by the Data class, then went to the business layer, then went to the GUI. But still went back to the Data class a couple of times when I realized some functionality I hadn't thought about (for instance, the save() method, which is called when the application finishes).