wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes (B&S) Write operations synchronization Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "(B&S) Write operations synchronization" Watch "(B&S) Write operations synchronization" New topic
Author

(B&S) Write operations synchronization

Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
I've read many topics on locking itself and I've found that my solution of LockManager is very similar to others.

But I have to ask although. I'm not sure how to synchronize the create/update/delete operations. When update (for example) occurs, it must be guaranteed that no one will unlock the record while updating, we can't check lock only before data update itself. Otherwise somebody could unlock the record just after the check.

This means another level of synchronization. I didn't find any post on this topic. For me candidate for synchronization is LockManager. Or should write operations performed from LockManager directly?

Thanks P.
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
Please, some tips?
Sergey Zolotaryov
Greenhorn

Joined: Mar 14, 2006
Posts: 26
What for to synchronize? Only one client knows the lock cookie. No one else does. So only one client can unlock the record the one, that locked the record and who is doing to update/delete it
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
Yes, but client could be teoreticaly multi-threaded. And I think it is good practice when writing server not to depend on the behaviour of client.

And you have to avoid creation of record with id that is still locked, thus I suppose you have to use something like this:



Otherwise (unsychronized delete) just after the real deletion, somebody can create record (potentialy with this recNo) and this new record is locked by some other client - not good :/
Sergey Zolotaryov
Greenhorn

Joined: Mar 14, 2006
Posts: 26
My point was not to do, what I am not supposed to do. You will have a greater chance of loosing points with a more complex approach. Keep it simple.

For a reallife system I would never invent any locking anyway. Its all written thousands of times before us.
sumuhan umamaheswarampillai
Greenhorn

Joined: Jun 19, 2002
Posts: 12
Hi Petr Hejl,
I hope I understoon you question correctly. I think you do need to synchronize.
first,You can safetly assume that clients are always single threaded.(unless you are developing a multithreaded client which is unlikely)

But in the case of the server things are different.
Server has to answer many clients at the same time and it is going to be multithreaded.

You locking code would work like this.

A) check if record is alrady locked.
B) If it is not locked then you lock it.
c) update the record
D) release the lock

It all seems fine if there is only one client at any given time. But there will be many clients. The server will user many threads to work with those clients.

Now think about this situation.

Client X does step A. Say the record is not locked. But just before it goes to step B and locks the record the thread is made it wait and another thread (for another client Y) starts working. That does step A. record is still not locked. now that read locks the record. Now that thread is made to wait. The first thread for client X comes back to work and goes to do step B. It doesn't know that another thread has locked the record while it is waiting.

To deal with this problem you have to Synchronize. When you Snychronize the block of code for step A and B you are saying "only one thread can be inside this block of code at any given time. Another thread can come in only after the first one has finished. So if the Thread for X is blocked between A and B then no other thread can go into the syncrhonized code so another thread can't mess things up.

Synchronizing is something you need to do when working with multiple threads in situations like above. And the requirements say you need a multithreaded server. So if you don't syncrhonize the locking won't work correctly and you may lose points

[ April 12, 2006: Message edited by: sumuhan umamaheswarampillai ]

[ April 12, 2006: Message edited by: sumuhan umamaheswarampillai ]
[ April 12, 2006: Message edited by: sumuhan umamaheswarampillai ]

SCJD
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
Thanks for answer but you probably misunderstood me.

You are describing bussines logic (I suppose) - it uses DB interface.
Lets look at this scenario (simplified meth. signatures):



These methods are that from DB.java interface, lock() itself is in some way synchronized (impl. detail) and guarantees that only one thread has locked record (if other thread will call lock it becames waiting). For me everything is perfectly clear till now.

Lest look _inside_ update method it could be (with use of some kind of lock manager and data source - single responsibility):


The trouble is that you must be absolutly sure, that nobody unlocked the record just after the check. So it seems to me that whole update have to be atomic (meaning nobody changed the lock during this).

LockManager provides synchronized implementation of lock(), unlock() and checkLock() but only this is not enough. You must be sure that current thread is owning lock for record during the _whole_ update()

P.
sumuhan umamaheswarampillai
Greenhorn

Joined: Jun 19, 2002
Posts: 12
public void update(int recNo, long lockCookie..) {
lockManager.checkLocked(recNo, cookie);
//How can anyone unlock here?
dataSource.update();
}


here how can anyone unlock after you have checked? To unlock they will need the cookie. So Why do you think this whole thing should be atomic?.
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
I think the server interface should be reliable by itself - it accessible through network. And we need to solve this for server. (Update is not the best example).



If one client calls delete and thread will be suspended (case with unlock) or client will perform some other operation before unlock (case without unlock in delete method) than if other client will call create than could (and probably will) receive record number that is still marked as locked.

Example without unlock in delete body:

A: DB.delete(5);
B: int rec = DB.create(); //receives 5
B: DB.lock(); //although this is new record from the B's point of view it is blocked until A will unlock 5

This can be partialy solved by unlock in delete, but thread can be anytime suspended before unlock => so race condition. So it seems to me that in delete there must be guaranteed the whole execution at once.
In this scenario no assumption on cookie per single threaded client will not help.

And little notice (to be absolutely clear) I'm not against anybody at all cost Just discussing the problem which I encounter and I should handle it in some correct way.

Thanks for your opinions.
[ April 12, 2006: Message edited by: Petr Hejl ]
Leo Ho
Ranch Hand

Joined: Mar 31, 2005
Posts: 36
Peter, if you already call lock() before calling update(), then why do you need this line in the update() body???

lockManager.checkLocked(recNo, cookie);

Regarding the delete(), create() issue, I don't reuse old records (those marked as delete) to avoid a bunch of problems.

Leo
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
It is because client of db calls lock and then update. Inside update method you have to check that it sends you right cookie and that the record is locked (method contract description). If client didn't send valid values you have to throw SecurityException.

P.
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
Any other propositions please?
Jan Kokenberg
Greenhorn

Joined: Dec 23, 2005
Posts: 3
I do not think you will need additional synchronization in your update method.

As long as one user has a the cookie value only that user will be able to work with that record. Other users will not have that cookie, since that cookie should be unique.

Once the record is locked nobody will be able to unlock it.
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
Yes, but if the server has public interface available through network, its functionality should not depend on correct behaviour of client (user). Client may run unlock and update concurrently (for some reason - multithreaded or evil client).
Jar Jaquiso
Greenhorn

Joined: Apr 20, 2006
Posts: 26
Hello Petr, your code

will not solve the problem if you are in a multithread enviroment because the clients call to unlock could execute between lockManager.checkLocked(recNo, cookie); and dataSource.update();.
If you want to solve the problem you must do so in the server. I've created a business object that locks, updates and unlocks the record, so the client is not even aware about any locking, the client only calls the update method in the business object, it knows nothing about the DBAccess interface.
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
Yes, exactly it was the example of wrong behaviour that I'm asking for. My solution is described in third post. This was the example for those who didn't understand what I'm asking for.

I've decided for networked db server (because of "Network server functionality for the database system"). I will create bussines layer of course, but located on client with notice in my choices.txt that better solution (if possible) would be to move this layer to server.
Jar Jaquiso
Greenhorn

Joined: Apr 20, 2006
Posts: 26
Ok, Petr, I've now seen what you're doing (third post) and, yes, that's another solution, synchronizing and re-checking the lock.
I've decided to have the business layer on the server 'cause it simplifies and controls access from the clients.
sumuhan umamaheswarampillai
Greenhorn

Joined: Jun 19, 2002
Posts: 12
Originally posted by Petr Hejl:
Yes, but if the server has public interface available through network, its functionality should not depend on correct behaviour of client (user). Client may run unlock and update concurrently (for some reason - multithreaded or evil client).


Petr,
Even though the lock and update methods are public you don't have to give access to them to the client when you build the RMI interface for the client.You can just give access to your 'business' method which handles the locking and unlocking. That should solve your problem I think.

I think adding extra code to protect the server from 'evil clients' is going a bit too far. An 'evil client' can possibly delete all records! You can see it is pointless trying to prevent that kind of things
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
I see the main trouble is that everybody suppose that there exist bussiness layer on server. But I've done the database system accessible through network (as written in assignemnt). Once you accept this I think there should be some kind of this synchronization.

One of item in "What you must do" is: "Network server functionality for the database system". So I choose to do it this way - database system (so DB interface) is accessible through network.
sumuhan umamaheswarampillai
Greenhorn

Joined: Jun 19, 2002
Posts: 12
One of item in "What you must do" is: "Network server functionality for the database system". So I choose to do it this way - database system (so DB interface) is accessible through network.[/QB]


I would like to make two points
first:
It is upto you to make the choice but I haven't exposed all the db interface methods through network server and I got full marks for Network Server. So I don't think this is a 'must' requirement.

Second:
Even if you do make all methods available to the clients I think it will be an over kill to add complex code in the server that deals with faulty clients. If you like you can add a line in your 'choices' saying you are assuming the clients are all good ones.

It is upto you, but as someone who has passed this exam my advice would be 'keep it simple'
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: (B&S) Write operations synchronization