Hey folks, just got this: Grade: P Score: 138 Comment: This report shows the total points that could have been awarded in each section and the actual number of points you were awarded. This is provided to give you per-section feedback on your strengths. The maximum possible number of points is 155; the minimum to pass is 124. Section Summary Report: General Considerations: Maximum=58 Deductions=9 Actual=51 Documentation: Maximum=20 Deductions=0 Actual=20 GUI: Maximum=24 Deductions=0 Actual=24 Server: Maximum=53 Deductions=8 Actual=45 Total: Maximum=155 Deductions=17 Certification Score=138 I knew that my doc and my gui have been very well, that was no question; and I asked myself how my locking and server solution would be honored - I personally think that it is very nice, a bit tricky (but not complicated) and in the sum: Just good. The evaluator seems to have a different point of view, and I think it's a pity that no further comments are given, so that I could discuss the result at least with myself... But who cares... I got it Next step: SCWCD, probably in February. Additional information: The result took 3 weeks, 6 days after the exam... Stay tuned Detlev
@ Mark The main question was: Should there be the possibility to identify a client or not. The answer in my opinion must be "yes", for the requirement: "If an attempt is made to unlock a record that has not been locked by this connection, then no action is be taken." If there would be no client identification, then it could not be under control who is the one trying to unlock a record. So I decided for client identification. The next question with this decision in hand was: How to implement it. I had decided to use RMI as the network communication approach, so I could not rely on a certain thread communicating with a certain client. That was the reason why I had to implement something like a connection ID (it also could have been a locking ID, but with a locking ID one would have to manage more ID's, whereas with a connection ID the client server sight is better documented: one connection ID for each client connecting to the server; I also added some extra information in the ID, the time of the connection, so it would be easy to add some functionality like maximum connection time or to add some statistical functionality like a server side table with all clients connected and their time being connected etc.; nothing of this is implemented, for there have no requirements been for that, but it would be very easy to expand the server side functionality with this information provided.) The next question was how to implement a good synchronization model. It would be a bad solution to synchronize on the whole database if one knows that just a certain record gets locked and that it would be enough to synchronize on this record. So on the one hand I needed a lock manager anyhow, on the other hand I had the solution with for the given problem with lock manager containing one locker object for each record - so these would be the objects to synchronize on! Not very difficult, and no more synchronization than needed. An extra question was what should happen if a client tries to lock a record which is already locked. It seemed too poor for me just to return an exception saying "already locked", because locking should not take too much time (the normal sequenze is lock-manipulate-unlock, and this will not take more than some seconds). Ok, so I implemented a queue for each record (in the RecordLocker, of course), where a client can get in with it's ID. Only if also the queue is full, the server response with an exception. With the idea of "locking will not take more than some seconds", it also made sense to guarantee this behaviour, on the one hand for the clients waiting in the queue, on the other hand answering the fundamental question what happens if a client locks a record and then dies without having unlocked the record before. So for each successful locking a CheckLockTimer will be instantiated, which will check after a certain amount of time if the record is still locked; in this case, the record will be unlocked, so the next client in the queue will get the lock. If the client first locking the record unlocks the record before the time given for locking, the CheckLockTimer gets canceled. With all this in hand, the next problem also was quite easy (and nice) to solve: The locking of the whole database. If a client wants to lock the whole database, no other client may lock a record. So the trick is to try to lock all records, and if this is achieved, the whole database is ready to be locked by one client. So if a client wants to lock the whole database, BlockingThread's are started, one for each record. The LockManager who tries to lock the database then joins all these threads, and then the LockManager has locked the whole database. I think it's a nice solution - what do you think?! [ December 11, 2002: Message edited by: Detlev Beutner ]
... BlockingThread's are started, one for each record. The LockManager who tries to lock the database then joins all these threads, and then the LockManager has locked the whole database. I think it's a nice solution - what do you think?! [ December 11, 2002: Message edited by: Detlev Beutner ][/QB]
Hi Detlev, Congratualations, great achievement! Nice that you describe your solution in detail. But with regard with the total lock, I can think of one drawback: you start up 1 thread for every record in the database. A thread takes several Megabyte RAM initially, and also consumes other system resources like file pointers. So, if the database has enough records, the system will slow down or crash... /Hugo.