• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

unlock a deleted record, how to?

 
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

This is for B&S, but should apply to other assignments.
Assume the client's call sequence for deletion is this



The problem is that unlock() will throw an exception since the record is already deleted, according to the programming spec., but I do want unlock() to successfully return as the client did nothing wrong.

Any suggestion how to implement delete() with locking?

Yan
 
Ranch Hand
Posts: 531
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Yan. This is what I did in my solution: unlock throws RecordNotFoundException if 1) a record is not locked and 2) record does not exist. Programmatically, this is expressed as (record is locked & record does not exist)
[ November 22, 2004: Message edited by: Anton Golovin ]
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Anton,

I'm not sure I agree with your algorithm. It basically says that an exception is thrown when you call unlock on an already unlocked, deleted row. What about an unlocked, non-deleted row? If you are going to throw an exception when a record is already unlocked, you should be consistent and not care about the delete flag.

My approach is to have the delete method unlock the record for you. I have a private unlock method that takes a flag defining if the unlock is coming from the delete code. The normal unlock calls the private unlock with the "from delete" flag unset. Delete calls unlock with the the "from delete" flag set. If the flag is set, unlock doesn't check if the record has been deleted.

My unlock also allows a user to unlock a record even if it was already unlocked. I don't think that unlocking an unlocked record should throw a RecordNotFoundException. If you really want to throw an exception when you unlock a record that is already unlocked, maybe an IllegalStateException would be more appropriate.

Josh
[ November 22, 2004: Message edited by: Josh Bjornson ]
 
Anton Golovin
Ranch Hand
Posts: 531
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Josh. In myy project, the method signature included the SecurityException, thrown if the record was not locked by user.
 
Josh Bjornson
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok. That makes sense then. I have a different signature and there are no SecurityExceptions at all.
 
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yan Zhou,在unlock里使用try-catch机制来解决你的问题。
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Zhong Bo Li,

Yan Zhou,在unlock里使用try-catch机制来解决你的问题。



Rough translation: "Use the try-catch mechanism in unlock to solve your problem."

Is that correct?

Please remember that although this web site is accessible all over the world, we need a common language so everyone can benefit. We have standardised on English (it is the language of the owners of the web site, and the majority of users know it). If you do want to post in Chinese, please also provide a translation so that others can benefit.

Thanks and regards, Andrew
[ November 23, 2004: Message edited by: Andrew Monkhouse ]
 
Zhongbo Li
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry,my english is very pool, I may reading and understand some discussion, but I feel defficulty to writing my point of view in english.

I guess that maybe the owner of the thread is a chinaman, so I post reply in cinese.

I'm sorry, I don't know here have standardised on English, I'll be in english later.
 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Yan


The problem is that unlock() will throw an exception since the record is already deleted, according to the programming spec., but I do want unlock() to successfully return as the client did nothing wrong.

Any suggestion how to implement delete() with locking?


If your problem happens in SCJD project, I think there must be something wrong with the delete-handle code. In the data file, there is a delete flag in head of every record. Delete method just modify the flag, but lock mechanism should face to the record. My proposal is deal with the delete flag as a field of database, then you can move on.

B.R.
Mike
 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yan,
how about this workaround solution:
throw the RecordNotFoundException at the end of the unlock method, ie AFTER you have done the unlocking ...

Just to fulfill the specification

How, what do the others think?
[ November 27, 2004: Message edited by: MF Tang ]
 
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I haven't finalized my solution on this, but let me offer a little brainstorming. And by the way, I used a map to keep track of locked records, where the (key, value) pairs are (recNo, lockCookie). So even when a record is deleted, its record number and the cookie used to lock it still exist in the lockedRecords map.

Just because a method is declared to throw an exception doesn't mean the method has to throw that exception. Take create, for example, which is declared to throw a DuplicateKeyException. Many people in this forum (including myself) have opted to never throw this exception from create due to the lack of a sufficient primary key to compare records with. Not to get off on a tangent, but I don't consider name + location to be a valid primary key, because it is reasonable to believe that there could be a contractor with more than one office/branch in a city the size of New York, for example. Anyway, the create method is declared to throw a DuplicateKeyException, but it is never thrown. The option is just there in case a sufficient primary key is supplied in the future (and as always, this is well documented).

Now back to unlock. I don't think it's necessary to ever throw RecordNotFoundException from unlock. Let's look at all the possible scenarios and how they should be handled:

Problem 1: unlock is called on a record that isn't locked
Solution: The record will not be in the list of locked records, so a
SecurityException should be thrown. This covers all cases where
an attempt is made to unlock a record that isn't locked.

Problem 2: unlock is supplied with the wrong lockCookie
Solution: Throw a SecurityException. This covers all cases where an
attempt is made to unlock a record without the proper cookie.

This leaves us with only one other scenario:

Problem 3: unlock is called on a record that is locked with the correct
cookie.
Solution: If the record's recNo is in the list of locked records, then
remove it from the list of locked records. It doesn't matter if
the record exists or not - if it does, then the record was just
updated, and if it doesn't, then the record was just deleted.
But DO NOT throw a RecordNotFoundException.

And here is my reasoning for the solution to problem 3. Even though the record doesn't exist, it is locked. In order for that record to be locked, it had to exist at the time that it was locked, or else a RecordNotFoundException would've been thrown. So basically, unlock is just a way to clean up your lockedRecords map and notify waiting threads that they can attempt to lock the newly-released record. If you just unlocked a record after deleting it, then the next thread will throw a RecordNotFoundException when it attempts to lock it.

Now I know, we have to take the following specification into consideration:

Any methods that throw RecordNotFoundException should do so if a specified record does not exist or is marked as deleted in the database file.


But isn't it acceptable to document your decision to not throw a RecordNotFoundException from update by arguing that the only reason a record number is supplied to update is to clean up your lockedRecords map, not to check if the record still exists, and that RNFEx isn't necessary because it was already checked for by calling lock, and that by not calling lock would lead to a SecurityException? Also, notice that sun said you "should" do so, NOT "must" do so.

Any thoughts?

[ November 29, 2004: Message edited by: Jared Chapman ]

[ November 29, 2004: Message edited by: Jared Chapman ]
[ November 29, 2004: Message edited by: Jared Chapman ]
 
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have just started monitoring this site because I am contemplating my readiness for and attaining the SCJD. I have not downloaded the assignment, and I have not seen the specs.

That said, here goes. If the unlock() method per the specs must throw a RecordNotFoundException, which you really don't have to do anything with, why not the following?
 
Ranch Hand
Posts: 456
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
many good points about this issue in the above text.

here comes my understanding:
obviously the developer has to ensure robustness of his code. for this reason unlocking unlocked or non-existing records shouldn't result in non-deterministic behaviour.

i just finished the data layer of b&s, now turning towards RMI and GUI.

my plan is to put the unlocking action (which actually means removing a record object from an ArrayList) in the implementation of the delete method. the GUI does not need to call unlock explicitly, but if called, nothing "bad" happens.

KISS, keep it stupid simple.
 
Ranch Hand
Posts: 145
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Am I stupid wrong. Does Sun change the requirement? The stupid simple is don't implement delete beyond access layer. Your won't get any credit for the thing that isn't required. Check your document. I only implement book and find operations at the business layer. According to Yan's original posting, the question is above the data access layer.

Or may need one more operation in business layer: close database if you leave your db handler always open. But it is not that important, since jvm in which handler opens dies, system should close it for you. It is just not that nice, though.
[ December 02, 2004: Message edited by: Andy Zhu ]
 
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Andy,

Bold move. I originally figured I'd implement bare bones search/book only functionality. I talked myself out of it after reading about what other people were doing on this message board - figuring it was better to do too much than leave out some important inferred requirement.
But now that you brought it up...
The DBAccess interface requirements suggest features that are not addressed in the business layer list of 'must haves'. Does anyone know if we are required to provide a GUI interface to delete, create, and/or edit records? If not, does that mean that we provide DBAccess implementations that never get called in the system as delivered? Seems too good to be true.

[ December 02, 2004: Message edited by: Bridget Kennedy ]

[ December 02, 2004: Message edited by: Bridget Kennedy ]
[ December 02, 2004: Message edited by: Bridget Kennedy ]
 
Andy Zhu
Ranch Hand
Posts: 145
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Bradgit:

I assure you that only book and find ops are required in gui. So we only need to expose these in business layer. However, keep in mind that you test other implementations (create, delete, etc) correctly in your access layer. I also assure you that Sun will test these: one of the reasons for having an universal interface.

I am still in testing now. But numerous posting talked this. I am not the inventer.
 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Bridget,

Originally posted by Bridget Kennedy:
The DBAccess interface requirements suggest features that are not addressed in the business layer list of 'must haves'. Does anyone know if we are required to provide a GUI interface to delete, create, and/or edit records? If not, does that mean that we provide DBAccess implementations that never get called in the system as delivered? Seems too good to be true.



We do not have to provide any GUI functionality beyond searching (usually just on two fields) and booking a record (updating one field).

There have even been some people who have passed without implementing the create and delete methods in the Data class itself. Their logic (as I understood it) was that these methods are unused, and so they could throw UnsupportedOperationException and still claim that they have implemented the method. However this is dangerous - you have to make sure you explain clearly your reasoning (both in the JavaDoc and in your design decisions document), and you have to hope that the assessor reads your comments and agrees with your reasoning. At least one person has failed as a result of the assessor not agreeing.

My recommendation would be to fully implement the create and delete methods according to the provided instructions. Test it fully, but don't use it in your GUI.

When writing your code, you should still write your code such that future enhancements can be easily added to your system. For example, don't make it hard to add a third search field in your GUI, and don't make it hard to add a create function in your GUI later.

Regards, Andrew
 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I state at the Data.java class that unlock() method is not called after delete() method. The delete function needs to wake up all the threads waiting for the record, but my unlock method wakes up only one thread. Just my 2 cents.

Rgds,
Clivant
reply
    Bookmark Topic Watch Topic
  • New Topic