This week's book giveaway is in the Java 8 forum.
We're giving away four copies of Java 8 in Action and have Raoul-Gabriel Urma, Mario Fusco, and Alan Mycroft on-line!
See this thread for details.
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Is there any benefit in the RMI Factory solution - when you have a lock cookie in your interface? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Is there any benefit in the RMI Factory solution - when you have a lock cookie in your interface?" Watch "Is there any benefit in the RMI Factory solution - when you have a lock cookie in your interface?" New topic
Author

Is there any benefit in the RMI Factory solution - when you have a lock cookie in your interface?

Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

I have had look at Andrews book and how he used the RMI Factory solution to uniquely identify clients. After an initial read, I had a few things I was interested in figuring out:

1) Would this work with my design of making the Data class a singleton (it's a singleton because I store my records in a cache in the Data class)?
2) What actual benefit will I get from this approach?
3) Will it solve the problem of prevent multiple requests to the lock-method to hang?

My Starting Point...

I have the following in my design:

1) My DB API has a lock cookie in it.
2) My Data class is a singleton.
3) My Data class has a cache containing the records.
4) I have a business service class which interacts with the Data class.
5) The client code never interacts with the Data class directly, it only interacts with the business service class.

My Main Goal...

My main goal here would be to solve the problem of when the same client calls the lock-method twice on the same record, one call directly after another. Instead of the second call to the lock-method causing the client to hang I want to identify that the client already has this record locked and prevent it from waiting indefinitely - either by throwing an exception or returning .

In order to do this I need to have some check inside my lock method of the form

RMI Factory Solution...

The RMI Factory solution from Andrews book will not work because the solution involves creating a separate instance of the Data class for each client. This is impossible if your Data class is a singleton.

Now, if your client never interacts with the Data class, but instead with a business service class, then you could look at creating a separate instance of this for each client. But what would that give you?

So in your client code you would be calling something like:

Assume of course that we are in network mode, that would give you back an instance of your business class, say RemoteService.

Right, so the client has a unique instance of the RemoteService class. But what does this actually give us? Will it allow me to identify a client in my lock method?

In my RemoteService class I will have a method like bookRoom(), which will go something like

So inside my lock method I still will have no way of knowing what client is executing the lock method.

One way of getting around this is to do as Roel suggested - set the client id on the data class before calling the lock method i.e.


Then in my Data class I would have something like:


So what does this actually give me in terms of setting my Data class up so that it prevents a second call to the lock-method by the same client to hang?

Well, in a round about way I have effectively added another parameter to my lock method by specifying that you must call the setClient-method before the lock-method.

Analysis of Solution...

1. Synchronize multi-operations

You definitely have to synchronize the this block of operations:


2. It doesn't prevent multiple calls to lock from hanging in your Data class

The solution to "prevent" multiple calls to the lock method from hanging is not a solution in the Data class. It is a solution that is spread across your business class and your Data class.

There is nothing stopping some one else taking your Data class and locking twice on the same record and hanging.

So in terms of designing the Data class to prevent multiple requests by a client to lock the same record, I don't think this design solves that problem.

In terms of my business class I don't see what it adds either. These aren't asynchronous calls. If a client calls the book-method on my business class, they can't call the book-method again until the first book method returns. So without this RMI Factory solution it is simply not possible to

3. Why an RMI Factory?

All the RMI Factory does is to allow me identify the client in my Business Service class. I could have achieved this in other ways that are possibly a lot simpler? Simply by adding an extra parameter to my book-method in my business service class, to allow a client to set its own id?

Conclusions...

1) Would this work with my design of making the Data class a singleton (it's a singleton because I store my records in a cache in the Data class)?

Yes. Just create unique instances of the Business Service class.

2) What actual benefit will I get from this approach?

None that I can see. It was never possible for the client to call the lock-method multiple times in the first place (either directly or indirectly) - because they only have access to the business service.

3) Will it solve the problem of prevent multiple requests to the lock-method to hang?

No. There is nothing stopping someone taking the Data class and calling the unlock method twice on the same record if they so wished.


SCJP (1.4 | 5.0), OCJP (6.0), OCMJD
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

Would be great to hear feedback on my analysis from any of you guys that used an RMI Factory (or similar solution), or anyone that prevented a second call to the lock-method from waiting forever.

Does my analysis sound correct? In particular I am interested on view from points (2) and (3) from my conclusion.
Sarah Archer
Greenhorn

Joined: Jul 25, 2010
Posts: 19
Interesting post. A few comments:

  • In my opinion Andrew's book uses a factory because his DB interface does not use a lock cookie and he used a fat client approach with his remote interface similar to his local interface. Therefore, the database needs to "know" which client has locked the DVD
  • I went for a fat client approach which meant I risked dropping locks if the client crashed. I therefore used a factory to track the client, the locks allocated, and if the client had crashed.
  • I think attempting to prevent a second call to a lock-method is flawed as it changes the behaviour of the Data class. The risk of lock up is an inherent feature of the specification
  • I think the implementation you propose is very risky. If an automated test harness were connected your data object, it would not know to call setClient() as this method is not in the spec. If the test harness attempted to lock an already locked record on a second thread it would throw an exception. And as you state a client can get round the logic in the business class by calling the Data object direct.
  • I get nervous about code that assumes that hashCode() is unique() but this is easily remedied


  • Regards
    Sarah
    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 4925
        
      10

    First of all, it's a nice analysis

    Although I was a bit confused that in the beginning you wanted to expose your (singlrton) Data class through the RMI factory. That was a bit weird, because in your situation you should expose your business service. Andrew's sample code is a bit different, because he exposes all methods from the given interface (and he thinks according to instructions that's the way to go, a very lengthy discussion can be found here).

    You could (as you already mentioned) simply expose your business service and add a setClientId method to your interface. This will definitely make your lockCookie unneeded. It adds extra complexity without a real benefit and could easily be simulated with adding an extra parameter to the book-method.

    When having a lockCookie in your interface I would not try to identify the client with an extra id, because it might confuse people (why do we have that lockCookie in our interface).

    Commenting on your conclusions:

    1/ Indeed

    2/ That was another remark why I thought you mixed up the assignment and the good api design part. If you work with a business service, it's quiet normal that the client can't call the lock-method multiple times, because it's not exposed So it was certainly not necessary to add this check to the Data class (but I did it just to assist a new developer working with my code).

    3/ It will certainly not prevent all possible multiple-lock-requests, but it will prevent some situations. It's not like the update-method where every call to update (without calling the lock-method for that record) will result in an exception. But because I could easily verify if a client locked more than 1 record at a time, I decided to add this check (it gives me 80-85% protection with just adding a few lines of code)

    Now I go (busy day tomorrow)


    SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
    http://www.javaroe.be/
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Is there any benefit in the RMI Factory solution - when you have a lock cookie in your interface?
     
    Similar Threads
    Scaratching left side with right hand - Client identification with service instance
    lock/unlock
    Multiple lock requests on the same record number
    RMI, business logic
    How does multiple calls to lock cause Deadlock?