aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Deadlock during record locking Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Deadlock during record locking" Watch "Deadlock during record locking" New topic
Author

Deadlock during record locking

Attila J�borszki
Greenhorn

Joined: Oct 11, 2008
Posts: 13
Hello,

What do you think, is it a problem if a client locking the same record twice causes deadlock? Should I handle this situation: a client wants to lock a record twice or more?

Or is it enough if I mention in the decisions doc and in the javadoc comments that this situation will cause deadlock?

If I should handle locking the same record twice or more by the same client, should I count the locks on a record to ensure that the client unlocks all locks before the other client can access the record?

In "SCJD Exam with J2SE 5" book example, locks on a record are not counted and a client locking the same record twice or more can cause deadlock.

Thanks,
Attila
Liviu Carausu
Ranch Hand

Joined: Oct 07, 2004
Posts: 158
Hi Attila,
My specifications of the lock method says that
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.

I interpret this as when a client tries to lock multiple times the same record, it must not block. The same mechanism like entering a synchronized block when the current thread already owns the lock for that synchronized block.
Greetings,
Liviu


Oracle Certified Master Java SE6 Developer(SCJD),
OCE JEE 6 JSP and Servlets Developer.
Attila J�borszki
Greenhorn

Joined: Oct 11, 2008
Posts: 13
Originally posted by Liviu Carausu:
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.


Thanks Liviu!

My specification of the lock method says that

If the specified record is already locked, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked.

According to my specification, I could say that the deadlock is the required functioning if the same thread locks the same record more times ...
[ November 11, 2008: Message edited by: Attila J�borszki ]
Liviu Carausu
Ranch Hand

Joined: Oct 07, 2004
Posts: 158
Hi Attila,
It looks like Sun found a nice way to specify complete different requirements only by omitting or adding a few words.
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2266
    
    3

Guys, here's what I did: when a client that already owns the lock of a record tries to lock a second record, I throw an IllegalStateException, saying that one client can only lock one record at a time.


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Liviu Carausu
Ranch Hand

Joined: Oct 07, 2004
Posts: 158
Hi Roberto,
How do you identify a client ? Do you have a Data instance for every "service" request , and all the calls done using that "service" are considered as being done from the same client ?
Thanks,
Liviu
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2266
    
    3

How do you identify a client ?


Ha! That's the real challenge of the URLyBird assignment! By the way, your assignment is the URLyBird, right?

In order to identify a client, here's what I did: first, my remote server has a method called lock that also takes a long. Here's its signature:



When I'm about to book a room, I generate a long value that will identify the remote client. Here's what I do:



This way, no way 2 different clients can have the same ID when booking a room.

My Data class actually implements an interface that I created (which I called DB) where I added a few extra methods, and extends the DBMain interface (the one you're required to implement). In this DB interface, I added a method called setClientId, that takes a long value as parameter (the same one that is generated in the client side). Then, when working in networked mode, when the server's lock method is called (and the server class has a reference to the Data class), I call the setClientId in the Data class, passing the long value as parameter, then call the Data class' lock method. In the lock method of the Data class, here's what I did: I verify if the clientId variable is null; if so (then it is running in standalone mode), I use the Thread's Id. I had to do this because, when using RMI, it is not guaranteed that the same Thread that handles the first request of a client will also identify their subsequent calls.

One observation is that, on the server class, I used the wait(); method while the record to be locked is still locked. On the Data class, I used the wait(); method as well, while the HashMap where I keep the locked records contains the record to be locked as key.

Take the time to read my solution. If you have questions, I'll be glad to clarify them.
[ November 17, 2008: Message edited by: Roberto Perillo ]
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
Hi Roberto.

How many points did you get for locking and for database access? (Just to be sure that the method you propose is considered "ok" by the assessors).


SCJP 1.4 100%
SCJD 99.5%
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2266
    
    3

Locking: 80 80
Data Store: 40 40
Network Server: 40 40

My complete score can be seen here.
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
Thanks.

The difference I see between your assignment and mine, is that in mine I have a lock method that returns a cookie. This cookie should be kept somewhere on the client-side and the client should invoke unlock using that cookie. This is the way a client is identified, not by thread id, Data instance or anything else (at least that's what I implemented). So, if in lock() I do not have the client's cookie, how can I know which client invoked the lock() method?

I think I'll just skip this "requirement" and document this in the choices file. In fact, it is specified only that a "different client" should give up CPU. Nobody said that the same client shouldn't do the same...

Anyway, I'm using a three layer architecture, where the same client can never try to lock unless it unlocks first, so such thing can never happen. But I just wanted my Data class to be usable in a two layer just the same...
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
Anyway, I'm thinking also at the usual deadlock, when two clients already own some locks and try to lock the other's client record. This kind of deadlock can be avoided only by specifying that clients must always lock their records in the order of their ids.

This is not specified in the DB interface, but it's regarded as an acceptable way of avoiding the deadlock issue. Why wouldn't this kind of approach be also acceptable for the one-client/same record issue? - just specify that the user shouldn't do that.

I think I'll do just that. Take a look - I think this two statements go very well together, and I see no contradiction :

"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. The situation when a client tries to lock the specified record while already holding its lock may lead to a deadlock, and it's the responsibility of the client to avoid it. Calling unlock() on this specific record before locking it again is enough to fulfill this requirement."
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2266
    
    3

Hey, partner.

I understand your point, and it makes a lot of sense. However, I think that, in your case, you just have to compare if the cookie that you receive as parameter in your update method equals the one that is saved where you keep your locked records, and if the record is the same for that value. If so, go ahead and update it, otherwise you can just throw an IllegalStateException. Now, if the record to be locked is already locked (when calling the lock method), you wait while the record is not unlocked. I just had to do what I described above because my lock method does not return any value.
[ November 17, 2008: Message edited by: Roberto Perillo ]
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
I was not referring to update/delete/unlock. The problem occurs only when the same client tries to lock the same record twice, without first unlocking it.

The Data class is not aware that the client already has the lock on that record. So the client has to wait for itself giving up the lock, which might not happen, if it keeps retrying to acquire the same lock again and again.

That is the problem. I was thinking that there might be a way to identify the client inside the lock() method and let it acquire the lock if it already has it. I can't think of a really good solution for this with the cookie approach...
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2266
    
    3

Oh, right. I had thought about a different situation.
You then might consider the solution I addressed above. It is certainly not the only possible one, but works successfully.
Or... I'm not really sure if you have to consider this scenario. Anyway, a friend of mine also has this certification, and I know the lock method of his interface returns a value. I'll ask him if he considered this scenario and will let you know.
Liviu Carausu
Ranch Hand

Joined: Oct 07, 2004
Posts: 158

Ha! That's the real challenge of the URLyBird assignment! By the way, your assignment is the URLyBird, right?

I have B&S. I have choosen a three layer aproach and a factory for creating service references. In my implementation, each client is associated with a service reference. This reference is used by the client to make remote calls.
Greetings,
Liviu
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2266
    
    3

Alecsandru,

as I told you yesterday, I spoke to the friend of mine that also has this certification. He told me that he didn't even care about the situation you described above (when the same client tries to lock the same record twice). And just so you, he got 80 points on Locking Mechanism and 40 points on Data Store.

Now, it's up to you.
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
Thanks a lot!

Do you know, did he also have this particular statement in the DB interface documentation? (This way I'll truly forget about this issue )

"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"
[ November 18, 2008: Message edited by: Alecsandru Cocarla ]
Liviu Carausu
Ranch Hand

Joined: Oct 07, 2004
Posts: 158
Hi Bob,
Thanks for your detailed answer.
In order to identify a client, here's what I did: first, my remote server has a method called lock that also takes a long. Here's its signature:
code:
public void lock(final int recNo, final long clientId) throws RecordNotFoundException;

I have a similar solution. I have such a lock method in my LockManager. But, instead of generating an additional client id, I use a Data instance instead. I hope that my solution will also be accepted
Thanks anyway for your time, partner.
Samuel Pessorrusso
Ranch Hand

Joined: Jul 21, 2005
Posts: 164
Thanks a lot!

Do you know, did he also have this particular statement in the DB interface documentation? (This way I'll truly forget about this issue )

"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"

[ November 18, 2008: Message edited by: Alecsandru Cocarla ]


I am the one who Roberto is talking about... Yes I have got this sentence in the assignment when I took this certification (2 years ago, I believe). I can not tell you the solution, all I can tell you is that YOUR ASSUMPTIONS are VERY important. You can implement almost anything if you have the correct assumption. Requirement gathering is also a requirement for this certification, you must prove that you know how to read and understand the list of requirements.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Deadlock during record locking