This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Lock and unlock implementation in business level Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Lock and unlock implementation in business level" Watch "Lock and unlock implementation in business level" New topic
Author

Lock and unlock implementation in business level

Sergey Bylokhov
Greenhorn

Joined: Dec 21, 2009
Posts: 14
Hello Everyone,

First of all thanks for this forum.

Some information about my decisions:

I have a B&S assignments.
My DBMain looks like


etc.
So there is no information about client cookie.
The comments are:
Locks a record so that it can only be updated or deleted by this client.


How to ensure that only a particular client can perform a particular operation?
I want to avoid the entire challenge, and declare that I am only providing business logic methods to the client software - this is a valid design decision?

So I implement all my logic in bussness layer. I`ve got example here:
http://www.coderanch.com/t/475511/Developer-Certification-SCJD/certification/RMI



I have some questions:
1 Its normal that i aggregate DBMain in Services instead of inherit it?
2 I use ReadWriteLock instead of lock - unlock methods from my DBMain interface. It seems to me it works in my program. Is it ok?
3 As far i understand i must implement lock,unlock,delete,islocked methods even if i do not use it Because it can be checked by SUN. But how i can implement it with this requirement for lock method "Locks a record so that it can only be updated or deleted by this client." Do you have suggestions for it?

Thanks
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5126
    
  12

Hi Sergey,

Welcome to the JavaRanch!

Most important remark: Not using lock/unlock methods from the DBMain interface will result in automatic failure, because locking facility was implemented incorrectly (not according to the instructions and it is a must requirement).

Using a business service is a valid design decision (I used it too), but your Data class MUST be made thread-safe (capable of handling multiple requests) and all methods in the given interface must be implemented, also when method is not called from the rest of your application (like delete and create method)

Your interface doesn't have a lockCookie, so you will have to come up with some way to uniquely identify the different clients (and RMI doesn't guarantee that 1 thread will handle all consecutive requests from 1 client). You could use a Factory pattern applied to RMI (as described and used in Andrew's book). Or you could use a unique client id (I used that one), more info about that could be found here.

Kind regards,
Roel


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2258
    
    3

Howdy, Sergey. Welcome to JavaRanch!

How to ensure that only a particular client can perform a particular operation?


Champion, please take a look here and here. Now, if you chose to have a thin client, then you can create a remote interface with a method called bookRoom() that can expect a client ID, which is a number that you generate on the client side and pass it to the server to identify the client. On the client side, you can apply the approach I presented in the 2nd link. Or, if you want to have a thick client, then you'll have to control the clients identification on the client side.

I want to avoid the entire challenge, and declare that I am only providing business logic methods to the client software - this is a valid design decision?


You mean, the client side will have no business logic? Yes, it is a valid approach!





Champion, I don't know if having the business classes as singleton is a good design decision. I'd say that it would be better if they were not sigleton.

1 Its normal that i aggregate DBMain in Services instead of inherit it?


Oh, absolutely. In the standalone mode, you'll end up having to do this. In the client mode, you'll use the Remote API, and it will use the Data object.

2 I use ReadWriteLock instead of lock - unlock methods from my DBMain interface. It seems to me it works in my program. Is it ok?


Hum... let's say that I have a method that expects the DBMain interface, and I use your implementation of the Data class. It won't work. So, to promote reusability, the locking mechanism has to be controlled with the methods provided in the DBMain interface.

3 As far i understand i must implement lock,unlock,delete,islocked methods even if i do not use it Because it can be checked by SUN. But how i can implement it with this requirement for lock method "Locks a record so that it can only be updated or deleted by this client." Do you have suggestions for it?


I'd say that, if you are not using them, then it is pretty likely that you are controlling the locking mechanism logic out of the Data (also considering what you said in your 2nd question). So, if you want to use your Data class, then you'll delegate the execution of these methods to another class, but it needs to be implemented in the Data class so the clients of this class can call it. Also, for this certification, you don't have to provide the delete functionality, but it must be implemented in your Data class.


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Sergey Bylokhov
Greenhorn

Joined: Dec 21, 2009
Posts: 14
Roel De Nijs wrote:Hi Sergey,
Most important remark: Not using lock/unlock methods from the DBMain interface will result in automatic failure, because locking facility was implemented incorrectly (not according to the instructions and it is a must requirement).
Or you could use a unique client id (I used that one), more info about that could be found here.


Thanks for help Roel.
I replace ReadWriteLock in my business layer with my DBMain lock-unlock methods. But i still do not understand you solution with yours DB interface and setClientId() methods.

How I understand it:
On client side:



On the server side:

And in DB interface in each method: update,delete,read,lock,unlock i should check clientid
fo example(all methods synchronized):



map just store information about locks (CLIENT<-->RECNO)

So i should describe in my choice.txt that client of my class should implemented every methods in this way?:


How do you think can i use this approach in standalone mode too and just throw IllegalStateException if clientid == null?



Thanks for help again!!!
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5126
    
  12

Hi Sergey,

According to your provided code samples you do understand my solution, because your code looks just fine. The data.setClientId(null); is not required (but I added them just to reset the value and add an extra validation: a client-id can't be overwritten by another client-id)

How do you think can i use this approach in standalone mode too and just throw IllegalStateException if clientid == null?

For standalone mode I didn't use the setClientId-method, that method is only for networked mode. In my Data class I just use the current thread id as clientId.

Kind regards,
Roel
Sergey Bylokhov
Greenhorn

Joined: Dec 21, 2009
Posts: 14
Roel De Nijs wrote:Hi Sergey,

According to your provided code samples you do understand my solution, because your code looks just fine.

Kind regards,
Roel


Hi Roel,Roberto
Thanks for your answers.
I look into it deeper (got code from Andrew's book) and think that Factory pattern more easy(do you know about disadvantages in this solution?).
But i still have a few questions about it:
1 Andrew in his book says that he do not want to make *Manager as a singleton but he make all field there as static. I look into this code and find this comments
/**
* A structure that keeps track of the locked Dvd records. Note that we
* have not made this static, as doing so would mean that only one set
* of reservations could exist at any given time. We rely on the class
* which uses this ReservationManager to ensure that only one instance
* exists for any reservations.
*/
private static Map<String, DvdDatabase> reservations
= new HashMap<String, DvdDatabase>();


In my implementation i made RecordLockManager and DataFileAccessManager as a singletons there is no static fields. Which uses only from my Data class.(I create Data objects for each network client).

2 What program should do if FileNotFoundException occured in RundomaAccessFile?(In this moment i wrap it in Data constructor and retrow DatabaseAccessException) But what next? should my application show the message and exit?

3 What should be done with InterruptedException in lock method? It should be retrow?

4 How to thow RecordNotFoundException in my lock,unlock,isLocked methods? Should I reimplement or just use read method before lock???
I mean some think like this(Note all methods in Data are synchronized)


5 What should do unlock method if the lock does not exists or if the lock exist but for another client?

6 What should be done if client lock the record and die after that?

7 What should be done with client if server die?

ps sorry for my english=)))

Thanks.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5126
    
  12

Hi Sergey,

For your question about the mistake in Andrew's book: there are some errata in the book which you can view on the website of Apress (don't know if that's listed there). On the other hand the book is just a guidance, not just copy-and-paste into your own assignment (otherwise SCJD would have no value at all), so you have to do some thinking about it. In fact if you just copy-and-paste the locking mechanism from the book, you will fail (because the writers broke deliberately a must requirement to prevent direct copying). You can read more about it in the Copying Monkhouse thread.

For all your other questions I would suggest try using the search engine, because I can remember all your questions being answered in the last month, some of them are still on the 1st page of the SCJD forum, like the one about InterruptedException. And if you really can't find the answer you can always start a new thread and post your question/problem.

And also try to follow the policy with regard to asking questions on JavaRanch (which can be found here) and more specific this item UseOneThreadPerQuestion.

Kind regards,
Roel
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2258
    
    3

Hey, Sergey!

Please take Roel's considerations. It's just that, this way, we can keep the forum well-organized, so more people can find everything in their places, and more people can benefit of the search of the forum.

And finally:



I did this because, in my lock() method, I verify if the clientId variable is null; if so, then I use the Thread's ID, so I have to ensure that everything is ok when I call the lock() method.
Bernd Wollny
Ranch Hand

Joined: May 15, 2006
Posts: 59

Hi guys,

nice discussion here... What about the client ID? Is ist enough to generate it on the client, e.g. with System.nanoTime(), or due to thread-safety this should happen on server side???
This would lead to antoher method within your RemoteServices like e.g. "getClientID()".

Best regards
Bernd


SCJP 1.4, SCJD/OCMJD
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2258
    
    3

Hey, champion!

It is enough to call System.nanoTime(). Also, since its purpose is to identify a paritular client, then it must be generated on the client side.

You don't really have to have another method called getClientID(). You just use it to identify the client, so it can be passed to the server in the book() method (in case of a thin client) or in the lock() method (in case of a thick client, you can create an interface that extends java.rmi.Remote and has a method called lock(), that expects a long).
Bernd Wollny
Ranch Hand

Joined: May 15, 2006
Posts: 59

Howdy Roberto!

I'm not sure it will be save enough to generate it on the client. I think a server-side clientID-generation will be more save due to different clients having their own times....
perhaps it will be save enough to pass SCJD?!?!?

Regards
Bernd
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5126
    
  12

Bernd Wollny wrote:perhaps it will be save enough to pass SCJD?!?!?

It certainly is: I used System.nanoTime(); just at the client-side and passed (added some remark about it in choices.txt, in future releases there could be a more safe algorithm, but for this assignment this will do)

Kind regards,
Roel
Sergey Bylokhov
Greenhorn

Joined: Dec 21, 2009
Posts: 14
Roel De Nijs wrote:Hi Sergey,

According to your provided code samples you do understand my solution, because your code looks just fine. The data.setClientId(null); is not required (but I added them just to reset the value and add an extra validation: a client-id can't be overwritten by another client-id)

Kind regards,
Roel


Hi Roel,

Looks like i rewrite all the code which i show in the first post in this thread
But what about


Thanks for help again!!!

Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5126
    
  12

Hi Sergey,

First of all I have no idea why you are locking/unlocking each record, just for getting a list of contractors. lock and unlock are only used to update or delete a record.

So you are right your read-method can throw a RNFE. You have some possible ways to handle it:
- just catch the exception (and ignore it because it can happen and it is considered as normal behavior)
- make from the call to find-method and each read an atomic operation, so RNFE (by the read-method) can never occur, because no other thread can swoop in between call to find and each read (hence the atomic operation)
- create an extra method in your own interface which returns for example Map<Integer, String[]> (so it returns the record numbers and the corresponding records) (the one I chose for my assignment).

Kind regards,
Roel
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Lock and unlock implementation in business level
 
Similar Threads
Terminology Clarification
About:My URLyBird1.3.2 Locking
URLyBird 1.3.3 Locking question
ReentrantReadWriteLock's lock mechanism
NX:About DBMain interface