This week's giveaway is in the EJB and other Java EE Technologies forum. We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line! See this thread for details.
i've implemented this interface and added two additional methods :
Now, when I'm writing the code, i'm reallizing that i have to alter both the public void delete(int recNo) method and the <v>public void update(int recNo,String data), to add an client identifier. I need a client identifier argument to identify whether a special someone does/doesn't hold the lock.
Of course, since i added another IF to my example, i could overload these two methods , to take the clientId as a parameter.
The question is :
How have you guys done this?
What have you done with the lock(int recNo) methods provided by Sun. I myself have implemented them to work using the Thread as an identifier, but annotated them with @Deprecated.
Your mechanism really works ( You might know that already ) ! But I spent a hell of a lot of time on getting my class to be as Thread safe and as fast as possible ( which are two things that don't go well together), so I'm not going to choose this approach, because it involves synchronizing on the whole data object.
The more I think about it, the more I realise that I'm trying to do more than Sun asks. Basically my interface just locks one record. It does not care if multiple clients call updates or deletes on that record. Why should I care?. The data class is supposed to handle concurrent updates on the same record. This locking mechanism just saves us from a bunch of nasty mean Threads which will want to update other records while we're working.
Given what Sun asks :
Your server must be capable of handling multiple concurrent requests, and as part of this capability, must provide locking functionality as specified in the interface provided above .
I think the best solution is to go with the simple plain old lock-one-record-no-matter-what-client approach.What do you say 'bout it?
Just one thing that you have to keep in mind Victor, let's say that I have an application that expects the interface that was provided by Sun. If I use your implementation of the Data class, is it going to work properly?
If I understand you correctly: client 1 locks record 1, then client 2 updates record 1 and finally client 3 unlocks record 1. That's a scenario that would be possible with your approach?
I don't think that's the way your Data class should work. Why would you then have to call lock and unlock before/after updating a record if you don't care about it.
Why you need a lock-method, you can read here in the scjd-faq
Joined: Nov 24, 2008
Glad you mentioned it, because i didn't think about this case.
client 1 locks record 1, then client 2 updates record 1 and finally client 3 unlocks record 1
The problem is like this : We have 3 clients.
Client 1 is locking record 1, Client 2 tries to lock record 1, but is waiting, Client 3 tries to lock record 1 but is also waiting.
Client 1 finishes it's work, Client 2 will add the lock to record 1 and so on...
This would be the normal behavior.
It might happen that after Client 2 obtains the lock, another Thread, just finishing it's job to remove the lock. Thus leaving Client 2 unable to update because a lock on that record does not exist.
The way I see it, a fix would be to increment a counter each time a record is locked, and decrement it each time a record is unlocked. What do you say?
What I say is easy: a record locked by client X can only be updated/deleted by client X and can afterwards only be unlocked by client X. If any client tries to update, delete or unlock a record without owning the lock on that record, will result in an (IllegalState)Exception being thrown.
No fuzz with incrementing and decrementing some counter.
Joined: Nov 24, 2008
Agree with you on that one , but that would imply
Either implementing sun's interface and adding an additional layer ( this was actually the first solution i implemented ), but frankly I don't know what to write in the lock() and unlock() method implementations in the interface provided by Sun. Or implementing the solution you proposed,which is nevertheless my second choice to the one I'm trying right now.