• 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

NX: Assignment - some design questions

 
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everybody,
I've recently downloaded the assignment as I intend to clear SCJD. It is much easier knowing that you guys are here and can help me with your opinions, as you�ve always did.
For a start, I have some design questions. I know that the design decisions should be all personal (and they will be) but I would like to know your two cents on the followings:
1) The assignment mentions that the application will be used by the client as an exercise before going to a web based system. In addition, the client does not expect much reuse of this application. In this case I wouldn't be concerned with a design that accommodates two databases because the future use of the application is uncertain. Even more, they mention that features that deviate from specs will not receive full credit. I know that you guys are discussing some designs that accommodate multiple databases, Lock Managers, but it looks to me the simple design suggested by Max in his book is appropriate (multiple instances of Data sharing static member).
2) I cannot find anywhere in the assignment saying that the record locked by a client can only be unlocked by the same client (Contractors assignment). Am I correct assuming that establishing locks on the records can be done at a minimum in this case keeping track of record#?
3) If the application is required only to search, display and book records, why would I care about deleting and adding records? I try to keep things simple here.
Thank you all for your feedback,
Adrian
SCJP, SCWCD
[ October 30, 2003: Message edited by: Adrian Muscalu ]
[ October 30, 2003: Message edited by: Adrian Muscalu ]
 
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Adrian,
Welcome to this forum.

1) The assignment mentions that the application will be used by the client as an exercise before going to a web based system. In addition, the client does not expect much reuse of this application. In this case I wouldn't be concerned with a design that accommodates two databases because the future use of the application is uncertain. Even more, they mention that features that deviate from specs will not receive full credit. I know that you guys are discussing some designs that accommodate multiple databases, Lock Managers, but it looks to me the simple design suggested by Max in his book is appropriate (multiple instances of Data sharing static member).


Definitely yes, a simple design as suggested by Max is appropriate and could lead you to get a high score for it.
But more complex designs are defendable to IMO, especially if you consider this assignment as a learning process. It's not the first time I do it, but at the end of this recent thread, I present a few arguments in favour of them. To that quite messy post, I'd add that I better remember and understand what I actually practice.

2) I cannot find anywhere in the assignment saying that the record locked by a client can only be unlocked by the same client (Contractors assignment). Am I correct assuming that establishing locks on the records can be done at a minimum in this case keeping track of record#?


Anyone out there with "Contractors" ?

3) If the application is required only to search, display and book records, why would I care about deleting and adding records? I try to keep things simple here.


I am afraid you won't find any possible simplification in that area. Your client must not implement create and delete, but you must implement them at the db level.
Best,
Phil.
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Philippe, thanks for the reply.
I think I'll go with something in between, a solution that adds a little more on the required functionality/design. That's the problem, once you open the door to improvements, it's hard to stop. And you can't tell when is the right time to stop.
By the way, the assignment doesn't say for whom is a "learning exercise", for the IT team or for the Customer Service .
[ October 30, 2003: Message edited by: Adrian Muscalu ]
 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Philipe,
Why is it that you insist that delete/update must not be available to the client?
The delete() and method in DBAccess will not be accessible unless you provide a GUI for it. (As no other method will delete a record as per spec.)
Also, if you leave out a GUI for delete and update then all you have left is create new and search and book. Is this what you are suggesting?
If so, the you suggest a very simplistic approach that I had not though of.
In my (submitted) assignmentI just used the schema to determine the look of my GUI and provided a very thin client that "used" all the methods in the DBAccess interface. And provided a JTable for search results. Do you think I will be penalised for providing an explicit update and a delete function?
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Adrian,

I think I'll go with something in between, a solution that adds a little more on the required functionality/design. That's the problem, once you open the door to improvements, it's hard to stop. And you can't tell when is the right time to stop.


I so much agree with you !

By the way, the assignment doesn't say for whom is a "learning exercise", for the IT team or for the Customer Service .


Do you really think they thought of the CSRs there ?
Best,
Phil.
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Do you really think they thought of the CSRs there ?
QUOTE]
Of course not, but I was pointing to the overall ambiguity of the assignment.

On the other hand, still no comment on the record lock. Why track users who lock when there is no need? I'd go with locking records only if they don't require something else.
Cheers,
Adrian

 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Nial,

Why is it that you insist that delete/update must not be available to the client?


Because each part of my assignment (DB/GUI/Network) have quite (un)precise specs. For the GUI client, I must provide book and search functionalities, period. Moreover, I do think that providing access to additional db functionalities may be undesired by the IT manager : is it the CSR's job to create/delete new records, or even update other fields than the "owner" one ? Now, it's clear that at the db level, createRecord() and deleteRecord() must be implemented as the Data class must implement the provided interface.
DB specs and client GUI specs are simply not related IMO.

If so, the you suggest a very simplistic approach that I had not though of.


Simplistic ? In you use Windows (and Java may tell you the OS you're running on), there is a very nice and useful functionality which may be executed by typing this command in a DOS console at the command prompt : "format c:". Even in the case it would be easy to execute it from your java application, would you get the idea to offer your CSRs a "Format C:" button ? Well, deleting records is quite comparable, though within a much more narrow domain.

In my (submitted) assignmentI just used the schema to determine the look of my GUI and provided a very thin client that "used" all the methods in the DBAccess interface. And provided a JTable for search results. Do you think I will be penalised for providing an explicit update and a delete function?


Oops ! I am afraid that it should be. Probably it will depend on how you justified it. What were your arguments ?
Now a question : your last post on this forum is dated 2003/08/21. When did you upload ?
If I made you feel afraid, I am sorry about it.
Best,
Phil.
 
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 Adrian,
Phil has already covered your other two points, so I am just going to comment on this one:

Originally posted by Adrian Muscalu:
2) I cannot find anywhere in the assignment saying that the record locked by a client can only be unlocked by the same client (Contractors assignment). Am I correct assuming that establishing locks on the records can be done at a minimum in this case keeping track of record#?


You are right - there are some versions of the assignment that do not state that only the locker may unlock the record.
But check your instructions for the lock() method. Doesn't it state that only the client who owns the lock may update or delete the record? So you still have to track ownership of locks anyway.
The instructions also state "This document deliberately leaves some issues unspecified, and some problems unraised. Your ability to think through these issues, in the face of realistically imperfect specifications, and come to a tenable solution is something upon which you are being graded. ".
Do you believe that it is tenable (defendable/reasonable) that a client may unlock a record they have not locked?
What would be the value of such a system?
On the negative side, I think I could write (bad) client software that always performs the sequence "unlock(), lock(), update() ..."
Without a positive reason for allowing any client to unlock any record, and with a potential for malicious misuse of that "feature", I would be very much against such a system.
Regards, Andrew
 
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 Niall,

Originally posted by Niall ORiordan:
In my (submitted) assignmentI just used the schema to determine the look of my GUI and provided a very thin client that "used" all the methods in the DBAccess interface. And provided a JTable for search results. Do you think I will be penalised for providing an explicit update and a delete function?


I agree with Phil that we should not allow clients to add or delete records. Basic security concept: don't allow dangerous actions unless explicitly asked for. The specification only asks us to allow the clients to search for and update records - nothing about adding or deleting records.
Furthermore I think that if someone tried to translate your stand alone client into a web client, and your stand alone client can do creation and deletion of records, then we are suddenly opening this functionality to the whole internet
And finally, you have to do more work (which is not required) to implement this - do you really want to give yourself more work to do?
But all of that is just my opinion (and would be my design decision (and hence in my design decisions document ))
However I disagree with Phil's statement "Your client must not implement create and delete". I think putting this as a "must" is too strong. The instructions are vague enough that I think someone could justify having the create and delete functions available to the client.
After all, the current client software is to be used in house, where hopefully the CSRs are trusted. And without this functionality in the client side, the company will have to create a separate application just to maintain the data.
You could even have a hidden switch to enable / disable that functionality. (As discussed in a previous topic, you could have a property in your suncertify.properties file which enables the add/delete functionality in your GUI, but not enable it to be changed from within the GUI - this is still OK (IMHO) since the examiner is not required to change this file in order to run your program, so you have not breached the requirements, but you have shown concern for security )
So having argued both sides of the fence ... my end comment is that this is yet another design decision for individuals to think about and document.
Anyone else want to add comments in favour or against either option?
Regards, Andrew
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Andrew and Nial,
I agree with Andrew disagreeing with me about my statement : "Your client must not implement create and delete".
As a matter of fact it was a "must not" of my own, not an excerpt of the instructions.
I'd better have written : "Your client should not implement create and delete in client, IMO".
Best,
Phil.
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you all for replying.
Andrew, I chewed a little on this record locking. You have a point saying that only the client that put a lock on a record has the right to unlock it. No argue here. I only suggested that I see no reason in keeping a reference to the client/data_object/thread that initiated the action, something like:

I am probably missing something here. I thought that this can be solved by implementing corectly the code in lock and unlockmethods. While Thread1 has a lock on Record1, any thread that intends to get a lock on Record1 waits. Who else can unlock Record1 other than Thread1?
Thanks for trying to bring some light into this.
Adrian
 
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 Adrian,

Originally posted by Adrian Muscalu:
You have a point saying that only the client that put a lock on a record has the right to unlock it. No argue here. I only suggested that I see no reason in keeping a reference to the client/data_object/thread that initiated the action, something like:

I am probably missing something here. I thought that this can be solved by implementing corectly the code in lock and unlockmethods. While Thread1 has a lock on Record1, any thread that intends to get a lock on Record1 waits. Who else can unlock Record1 other than Thread1?


Unfortunately while you are correct that client's will block if they try and lock an already locked record, this is not the same as saying that only the client that locked a record may update it.
You still have the loophole that client A could lock the record, then client B could just call update() without calling lock(), in which case your solution would not care that client B does not hold a lock - it will allow the update to go ahead.
Unfortunately you cannot even claim that it is only your client that will ever be used. It is quite possible that if they go to a web based solution, they may keep your server as the back end serving both local and web based clients.
To ensure that this does not happen, you are going to have to have some way of identifying the owner of the lock. Then within the update() and delete() methods you are going to have to verify if the calling client owns the lock, otherwise disallow the operation.
Regards, Andrew
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Andrew Monkhouse:
Unfortunately while you are correct that client's will block if they try and lock an already locked record, this is not the same as saying that only the client that locked a record may update it.


Now I see where you�re coming. But I still think you�re wrong.

You still have the loophole that client A could lock the record, then client B could just call update() without calling lock(), in which case your solution would not care that client B does not hold a lock - it will allow the update to go ahead.


Client B cannot call update() without calling lock(). It's part of the design. A client cannot directly invoke lock() or unlock(). Instead, has access to update(), add(), etc. The call to lock is part of the update() method in this case.
To conclude, when a client locks a record it means that it wants to perform an operation. The record gets locked until the operation is finished. When another client pops in (that is, wants to perform an operation, lets take update() for example) he cannot get a lock on the record because it is locked. He waits. He cannot perform that operation because he MUST obtain the lock first. Having this in mind, the requirement that says "a record can only be updated or deleted by the same client" is accomplished.


Unfortunately you cannot even claim that it is only your client that will ever be used. It is quite possible that if they go to a web based solution, they may keep your server as the back end serving both local and web based clients.


Absolutely true.


To ensure that this does not happen, you are going to have to have some way of identifying the owner of the lock. Then within the update() and delete() methods you are going to have to verify if the calling client owns the lock, otherwise disallow the operation.


No need to identify the client. The current client has the lock on the record and is the only one who can release the lock (remember, nobody calls unlock without having the lock first).
If Joe locked the record, I don't care if it was Joe. All I care is that nobody else but Joe can access that record until Joe finishes the operation and unlocks the record.
Regards,
Adrian
[ October 31, 2003: Message edited by: Adrian Muscalu ]
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Andrew and Adrian,

Andrew:
It is quite possible that if they go to a web based solution, they may keep your server as the back end serving both local and web based clients.


That sentence looks like you were still arging in "the big thread", and betraying your camp.

Adrian:
Now I see where you�re coming. But I still think you�re wrong.


Oops ! I wouldn't toss a coin on it, or then a rigged one. When Andrew is not wrong on purpose, he is right 95% of the time. It's annoying a bit but that's just statistics.

Adrian:
Client B cannot call update() without calling lock(). It's part of the design.


It's part of the specs. And it's up to you, thanks to your design, to fulfill those specs IMO.

A client cannot directly invoke lock() or unlock(). Instead, has access to update(), add(), etc. The call to lock is part of the upload() method in this case.


Sorry if I missed it from a previous post, but which version of the assignment do you have ? Are your lock() and unlock() methods provided by your DB access interface ?

No need to identify the client. The current client has the lock on the record and is the only one who can release the lock (remember, nobody calls unlock without having the lock first).


Here is what I think Andrew was thinking about : that your locking system ensures that good locking practice. For my assignment (URLyBird 1.2.1), it's quite clearly stated in the instructions. That's why I asked you above which version you had : most of them are very similar, but with subtle differences.

If Joe locked the record, I don't care if it was Joe. All I care is that nobody else but Joe can access that record until Joe finishes the operation and unlocks the record.


But you don't care that Jim uses Joe's lock to update the record in his place, or that Jim unlocks the same record, do you ? Now if your version use lock cookies, it may be different.
Best,
Phil.
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Philippe Maquet:

But you don't care that Jim uses Joe's lock to update the record in his place, or that Jim unlocks the same record, do you ? Now if your version use lock cookies, it may be different.


How can Jim use Joe's lock? How can Jim unlock the same record when the record is still locked?
Here is the scenario.
- Joe wants to modify the record1 and calls modify(1) method.
- method modify(1) calls lock(1). There is no look specified for record1 therefore Joe is the proud owner of a record. Record1.
- Joe starts the modifying process which happens to take long time.
- Jim wants to do something with record1
- Jim calls modify(1) anticipating Joe's face when dicovers the data integrity problem :-)
- method modify(1) calls lock(1). There is a lock specified for record1 therefore Jim waits.
Question: Can Jim skip the line and unlock record1 ?
NO, Jim only called method(1) that has the following flow of operations: lock, modify and unlock. Same for Joe.
The modify(1) method has no knowledge that the caller was Jim or Joe. Only does what is supposed to do. And the first thing it does is to get a lock on record1. It not possible, the Thread that called (Jim in this case) waits.
To clarify some things, I have the Contractors assignment. the signature of method lock is as follows:

The requierement states:
"Locks a record that so that it can only be updated or deleted by this client."

As a design model, I have a draft in which each client has it's own implementation of Data, methods are unsynchronized - no need to IMO since we have different objects for different clients. The locking mechanism is a class with a static List member that holds record id-s. Each Data implementation has a reference of this Lock class and calls it's lock(i) and unlock(i) methods.

Andrew, Philippe, please don't lose your patience on this. I want to be sure I'm right and I have understood the process.
Thanks a lot,
Adrian
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Adrian,

The requierement states:
"Locks a record that so that it can only be updated or deleted by this client."


I have a few questions. Where is your modify() method coming from ? Does it belong to Data ? (I ask that because mine is called updateRecord() and our assignments are different). If true, is it its responsabity to call lock() by itself or should lock() be called before (but independantly of) your modify() method ? Could it make sense that some programmer calls lock(), then read() to check if the record changed, before deciding to update() the record or not ?
Best,
Phil.
[ October 31, 2003: Message edited by: Philippe Maquet ]
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Philippe Maquet:

I have a few questions. Where is your modify() method coming from ? Does it belong to Data ? (I ask that because mine is called updateRecord() and our assignments are different). If true, is it its responsabity to call lock() by itself or should lock() be called before (but independantly of) your modify() method ?


Phil,
my modify() method is implemented in the Data class. The name is update() but is not the name we are after; it's the location. It is indeed it's responsability to call lock.



Could it make sense that some programmer calls lock(), then read() to check if the record changed, before deciding to update() the record or not ?


It makes perfect sense to do that since several threads might wait to get a hold on a particular record. Once they get a chance to do it, the record might be already deleted by one of the previous threads.
Thanks for replying,
Adrian
[ October 31, 2003: Message edited by: Adrian Muscalu ]
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Adrian,
The fact that you made update() call lock() looks weird to me. But if you do, reading your last paragraph, I suppose that you made lock() reentrant. Right ?
Best,
Phil.
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am not sure what reentrant means but once an object/client gets a hold on a record it checks if the record is still there. This is part of the lock method implementation.
It is also true that we might have the following situation: client1 is modifying record1, client2 tries the same and waits. Client1 finishes job, notifies and client2 locks the object, modifies it. This is some sort of "dirty modify" because client2 just modified a record he doesn't know. Should we take this into account? Not for this assignemnt I would say. This locking is so well implemented in a real database. I think we are fine for the assignemnt if we just identify this situation and document it.
What do you think?
Adrian
 
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 Adrian,

Andrew:
It is quite possible that if they go to a web based solution, they may keep your server as the back end serving both local and web based clients.
Phil:
That sentence looks like you were still arging in "the big thread", and betraying your camp.


Yep - exactly right
Adrian, you may be interested in reading the thread "Should lock methods be callable by the client" - it might help you understand what my arguments were about earlier. It sounds like you have already decided to join the dark side and hide the lock methods from the client though.
Since you are hiding the lock() and unlock() methods from the client, you are correct - you do not need to track ownership of the locks.

Adrian:
my modify() method is implemented in the Data class. The name is update() but is not the name we are after; it's the location. It is indeed it's responsability to call lock.


So as I understand this, your Data.update() method calls Data.lock() itself. In which case there is no value in Data.lock() being public. (But it has to be, since that is the signature in the interface - why do they have such an method signature then?)
This also means that your update() method cannot be generic. Your Data.update() method must check internally to see if the change is allowed (a record that is booked may be unbooked, or a record that is not booked may be booked).

Phil:
Could it make sense that some programmer calls lock(), then read() to check if the record changed, before deciding to update() the record or not ?
Adrian:
It makes perfect sense to do that since several threads might wait to get a hold on a particular record. Once they get a chance to do it, the record might be already deleted by one of the previous threads.


This is where Phil is talking about reentrancy - the ability of your code to behave correctly when it is called a second time. In the case above, some code external to Data class has called the lock() method (not the client, since I understand you are hiding lock() from the client), then calling Data.update() which internally calls Data.lock(). Now theoretically if you are not tracking who locked the record, this second call should block, even though it was the same client.

Adrian:
It is also true that we might have the following situation: client1 is modifying record1, client2 tries the same and waits. Client1 finishes job, notifies and client2 locks the object, modifies it. This is some sort of "dirty modify" because client2 just modified a record he doesn't know. Should we take this into account? Not for this assignemnt I would say.


I think it is essential that we take this into account.
Client 1 believes that they have booked this Contractor and paid their money. Client 2 believes that they have booked this Contractor and paid their money.
I cannot see how you could allow this.
The solution is very simple, and is the reason why we have a public lock() method. I will let you think about it before giving away the solution.
Regards, Andrew
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Andrew,
The link you've provided in the previous message had a strong impact on the way I intend to design. The thread was long, it took a lot to read but it worth it. I have no intention to go into details, I just want to say that my design fits in the 3-tier archiecture category. In other words, I consider myself part of the "Guinea pigs" team . While I understand your design I appreciate your determination to stick with the specs, I consider it not the best way to go.
Since in any design the client needs to make clear specs amd in this case the client is not to be found, I consider that he declined the invitation to discuss the details of the requirements. In this case I take a decision based on my professional expertise.


So as I understand this, your Data.update() method calls Data.lock() itself. In which case there is no value in Data.lock() being public. (But it has to be, since that is the signature in the interface - why do they have such an method signature then?)


My Data.update() calls indeed Data.lock() but the latter only dispatches to the lock() method of the LockManager class. It is this class that handles all the locking process and every instance of Data has a reference to it.


Client 1 believes that they have booked this Contractor and paid their money. Client 2 believes that they have booked this Contractor and paid their money.


Not exactly, at reentrancy each thread checks for deletion and for the booking status. This cannot happen.
What can happen (and my current design doesn't cover this yet) is that a client/CSRep modifies the name, location and other fields of a record while another one waits to re-enter. Since I only check for deletion and booking, the client might book a contractor that moved to a different location. I'll think about this.
I'm sure that whatever design will choose, we'll meet at the other side.
Phil, you've made an excellent case in that thread.
Regards,
Adrian
 
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 Adrian

Adrian:
The link you've provided in the previous message had a strong impact on the way I intend to design.


Fair enough - as long as you are aware of the issues, and are willing to defend your decision (that is: put it in your design decisions document - don't just do what you think is the better way of working without documenting why you did it), then you should be fine.

Andrew:
So as I understand this, your Data.update() method calls Data.lock() itself. In which case there is no value in Data.lock() being public. (But it has to be, since that is the signature in the interface - why do they have such an method signature then?)
Adrian:
My Data.update() calls indeed Data.lock() but the latter only dispatches to the lock() method of the LockManager class. It is this class that handles all the locking process and every instance of Data has a reference to it.


But can some other method in the server (or from the client) also call the Data.lock() method?

Adrian:
I'm sure that whatever design will choose, we'll meet at the other side.


Yep (as long as it is documented, and does not break a "must" criteria).

Adrian:
Phil, you've made an excellent case in that thread.




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


Andrew:
So as I understand this, your Data.update() method calls Data.lock() itself. In which case there is no value in Data.lock() being public. (But it has to be, since that is the signature in the interface - why do they have such an method signature then?)
Adrian:
My Data.update() calls indeed Data.lock() but the latter only dispatches to the lock() method of the LockManager class. It is this class that handles all the locking process and every instance of Data has a reference to it.
Andrew:
But can some other method in the server (or from the client) also call the Data.lock() method?


The client has no way to call it directly since I'll be having a Business tier in place and for the client only a method of type bookRecord will exist. Theoretically, the server can call lock() directly because the method is still public (I can't do anything about it). What I can do is to remove completely the functionality from the lock() method. The modify() method will call directly the lock() from the LockManager. This way I avoid any confusion.
Regards,
Adrian
 
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Adrian, guys!
The idea to call lock from update is a bit strange for me,
what you say about this ?(I think this is good illustration for previous post, what you say , Adrian?)

That's mean write all business code 1 level up, and use Data.class methods from
this level, alloving modify records only by lock owners, and not keep owner id
in massive of locks, as Adrian proposes.
[ November 02, 2003: Message edited by: Peter Kovgan ]
[ November 02, 2003: Message edited by: Peter Kovgan ]
 
Peter Kovgan
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I run test on my 1600Mhz CPU/512Mb RAM and results are:
50 simultaneously running clients try to make 100 updates (with sleeping from 1 to 100 mseconds) on the same record, without connection to Data file, but simply holding a lock of this record in Vector,and controlling this lock.
I've got 5000(sometimes 4995/6/7) updates.
Does this result say us my program works fine?
[ November 02, 2003: Message edited by: Peter Kovgan ]
 
Ranch Hand
Posts: 555
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,
I do not really understand why you call vector.wait() in Data.isLocked(int recNo) method... ?
Best,
Vlad
 
Peter Kovgan
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Vlad,
I can really call vector.wait() separatelly from another place,
for example from lock();
But my Contructors have Data.class , which implements(must implements)
public void lock();
public boolean isLocked();!!!
and so on...
I think it's better to leave all business methods in upper level(SomeAdapterClass), and call all Data.class methods from this
level, and not mix.
Why?
Cause,it's look like more object oriented for me.
I build Business level with methods bookContractor(), readAll() and leave all DataBase level methods (include isLocked()) in Data class, and think it's not fine call isLocked() from lock().
Generally, what you think about my design?
 
Adrian Muscalu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,
Calling lock() from update() was part of a test I made to prove a concept. In my implementation (for which I didn't write a single line of code yet) I'll have a Business Tier all right but the implementation will be slightly different.
Method isLocked(), along with lock() and unlock() will be called from the business tier on Data but they will have no direct implementation. They only dispatch to a LockManager class that is unique to all the clients. This is the place where the static vector will be in my case.


Does this result say us my program works fine?


Maybe. I don't see where you handled reentrancy. What happens if one record is beeing modified as another thread still waits for it? Once the latter will get his chance (and lock it accordingly), will modify a record that might not match the one a client viewed on the interface as result of a previous query. What if was deleted or booked in the meantime?
How can your unlock() implementation throw RecordNotFoundException? In the example you've provided there is no way. Unless you are just trying to prove a concept and the code is only an example.
Regards,
Adrian
 
Peter Kovgan
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Adrian!

Originally posted by Adrian Muscalu:

Maybe. I don't see where you handled reentrancy. What happens if one record is beeing modified as another thread still waits for it?


I think in update()...but I must think more

Originally posted by Adrian Muscalu:
How can your unlock() implementation throw RecordNotFoundException? In the example you've provided there is no way. Unless you are just trying to prove a concept and the code is only an example.


there is mistake..
Thank you for your reply!
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,
Or I missed something, or you mixed your isocked() and lock() codes :
  • isLocked() returns false all the time
  • isLocked() doesn't need its while loop neither the wait() call
  • lock() should have such a while loop along with a wait() call


  • Is a Vector of recNos enough ? Don't you need to track lock owners ?
    Best,
    Phil.
     
    Peter Kovgan
    Ranch Hand
    Posts: 84
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Philippe !
    Thank you for interest.

    Originally posted by Philippe Maquet:

  • isLocked() returns false all the time


  • Yes, and isLocking used only if client attempt to lock

  • isLocked() doesn't need its while loop neither the wait() call



  • My isLocked has function of LOCKER here, but I can change this.

  • lock() should have such a while loop along with a wait() call



  • Why? I lock record in isLocked.But I can change this.


    Is a Vector of recNos enough ? Don't you need to track lock owners ?


    No,I need not owners, if client A try book() and number of the record saved in vector(locked), he wait in isLocked() method
    while somebody, who have rights on this record, call unlock(),
    Who have rights? The boy who pass isLocked(thisRecordNumber).


    I can change my code and place wait in lock(), but generally are you agree
    we need not track owners?
    And else one question:
    Do you use ConnectionFactory? I think it's too complex for this project.
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Peter,
    Reading the first part of your post, I still didn't understand what you were doing in/with your isLocked() and lock() methods ... till I read your example where you make things clear.
    What I am afraid of is that your implementation - though working in your application context - doesn't fulfil SUN's requirements.
    Here are my own lock/unlock method signatures, along with their comments (which are part of the specs BTW) :


    // Locks a record so that it can only be updated or deleted by this client.
    // Returned value is a cookie that must be used when the record is unlocked,
    // updated, or deleted. If the specified record is already locked by a different
    // client, the current thread gives up the CPU and consumes no CPU cycles until
    // the record is unlocked.
    public long lockRecord(long recNo) throws RecordNotFoundException;
    // Releases the lock on a record. Cookie must be the cookie
    // returned when the record was locked; otherwise throws SecurityException.
    public void unlock(long recNo, long cookie) throws SecurityException;


    Could you post your version of those locking-related methods (including isLocked()) ?
    As you can notice, I have no isLocked() method in my own instructions. But it's clear that lockRecord() must wait.

    I can change my code and place wait in lock(), but generally are you agree
    we need not track owners?


    Depending on your own version of the instructions, I could reply : yes, no or maybe.
    So after you'll have posted them, we'll - hopefully - have some more useful discussion.
    Best,
    Phil.
     
    Vlad Rabkin
    Ranch Hand
    Posts: 555
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Peter,
    I agree with Phil:
    I still don't see ANY reason to put a thread in waiting state in your isLocked() method.
    Best,
    Vlad
     
    Ranch Hand
    Posts: 90
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi all,
    I can see the benefit of using a lock cookie to ensure that the client that locked the record is the one doing the modification, but...
    in the Data interface we/some of us are told


    // Locks a record so that it can only be updated or deleted by this client.
    // If the specified record is already locked, the current thread gives up
    // the CPU and consumes no CPU cycles until the record is unlocked.
    public void lock(int recNo) throws RecordNotFoundException;


    which makes the cookie solution harder to implement (as lock returns void). So would we be talking about not exposing the interface to the Client as specifed, but wrapping it in an Adapter class? If so, should we therefore go the whole hog and hide everything in a Buisness Tier
    More discussion would be helpful!
    Thanks,
    Steve
     
    Peter Kovgan
    Ranch Hand
    Posts: 84
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    Depending on your own version of the instructions, I could reply : yes, no or maybe.
    So after you'll have posted them, we'll - hopefully - have some more useful discussion.


    Philippe ,Vlad .
    You are right!
    My Instructions:

    and this is my new code:


    No need to remember owners?
    [ November 03, 2003: Message edited by: Peter Kovgan ]
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Stephen,

    I can see the benefit of using a lock cookie to ensure that the client that locked the record is the one doing the modification,


    Cookies are just an indirect (and imperfect) way we have in some versions of the instructions to identify a lock's owner.

    So would we be talking about not exposing the interface to the Client as specifed, but wrapping it in an Adapter class? If so, should we therefore go the whole hog and hide everything in a Buisness Tier


    Mmh... If I had to come here with arguments against the separate server-side business tier, Andrew would claim everywhere that I'm turning crazy.
    The key is that there is (or should be) no relation between the way you implement the provided DB interface and the application-as-whole architecture you chose (2-tiers or 3-tiers).
    I do think that the good way of working this assignment is doing, for each part of it, "as if" you were member of a team fulfilling its own specs. Of course you're alone doing everything. But that "as if I was just responsible for this part" really helped me - hopefully ! - to put responsabilities at the right place.
    When you think "db", just think "db" : the interface you were provided and its comments. Don't think how you will use that interface, but how anyone reading it could use it.
    Later you'll be thinking in terms of "application", playing the role of an architect. There, you'll choose (among other things) between a 2-tiers or 3-tiers architecture. But if your db work is well done, ideally such a decision shouldn't lead you to any db layer refactoring need.
    Could you post the comment given with your update() method ? If it's like mine, tracking the locks owner - even without cookies - is mandatory.
    Best,
    Phil.
    [ November 03, 2003: Message edited by: Philippe Maquet ]
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Peter,
    Your question first :

    No need to remember owners?


    You need it IMO. While you have no specific comments for update() and delete() as I have, your provided lock() method comment is clear enough :
    "Locks a record so that it can only be updated or deleted by this client.
    How could you ensure this if you don't track lock owners ?
    Now just a few comments about the code you posted (as you posted it, I guess I may comment it ) :
    isLocked() : You don't need the if-else construct.
    lock() : You probably read Max's book and it's a great one. But notifyAll() is useless in lock().
    book() : What's the int values you return ? What about making it void and just throwing exceptions to signal exceptional cases ?
    In general : Please don't hide unhandle exceptions in catch blocks the way you do. Hiding a problem when it happens (a catch block) without dealing with it (an empty catch block) is a good way of making your application behave weirdly (and making your examiner upset ).
    Best,
    Phil.
    [ November 03, 2003: Message edited by: Philippe Maquet ]
    [ November 03, 2003: Message edited by: Philippe Maquet ]
     
    Peter Kovgan
    Ranch Hand
    Posts: 84
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Phillippe, thank you, but I think in one question you are not right...

    Originally posted by Philippe Maquet:
    ...Locks a record so that it can only be updated or deleted by this client....
    How could you ensure this if you don't track lock owners ?


    Cause while client "B" has the lock, client "A" inside the while loop,
    periodically call vector.wait and do nothing.
    Only client, which has the lock can do unlock, cause
    lock() and unlock() called from the same method book().
    Client "A" can't exit from while loop, while client "B" has the lock.


    Now just a few comments about the code you posted (as you posted it, I guess I may comment it ) :
    isLocked() : You don't need the if-else construct.


    Yes, you are right, thank you.


    lock() : You probably read Max's book and it's a great one. But notifyAll() is useless in lock().


    Yes .And I know it too , but this piece of code
    leaved here by mistake.


    book() : What's the int values you return ? What about making it void and just throwing exceptions to signal exceptional cases ?


    I need to work here...
     
    Vlad Rabkin
    Ranch Hand
    Posts: 555
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Peter,
    I join to all statements of Phil.
    Phil:

    ...Locks a record so that it can only be updated or deleted by this client....
    How could you ensure this if you don't track lock owners ?


    Peter:

    Phillippe, thank you, but I think in one question you are not right...


    Well, Phil has another assignement, where the cookies are used to track the lock owner. His assignment defined SecurityException (which can actually never be thrown). It is not necessary to do in your case.
    There are other issues like client crash, where having a reference to the owner of the lock could help.
    Let's say this way: Strictly saying you don't need to track the owner of the lock in your assignment. I personally agree with you.
    To make your application more enhanced you will need to keep track of lock owners. Why? I would leave it for Phil, because it is his "favorite story"
    Best,
    Vlad
    [ November 03, 2003: Message edited by: Vlad Rabkin ]
     
    Peter Kovgan
    Ranch Hand
    Posts: 84
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    To make your application more enhanced you will need to keep track of lock owners. Why? I would leave it for Phil, because it is his "favorite story"
    Best,
    Vlad


    OK, client crash can leave locked record...I'm agree.
    How "WeekReference" can store references to clients?
    Thank you, guys, I feel I ask too many questions.
    I'll try to find somthing at the forum and at Google.
     
    What do you have in that there bucket? It wouldn't be a tiny ad by any chance ...
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic