Fog Creek Software
Discussion Board

Hope I don't look stupid - Java question

Hello Everyone,

I am bringing this question to this forum because I believe their to be a great deal of programming talent here. I am working on a project that I would eventually like to sell, but I don't have a lot of experience with object oriented web development or Java. (Ya, I know, don't use a technology you're not a master at to write something you want to sell, but what the hell. Worst case, I'll learn a whole lot!)

Here is what I am doing.

Side Note: I'm using the Nested Sets model to store a Tree Structure in a DB.

I have a Java Bean that represents a Node in the Tree Structure, let us call it “The Node Object” (TNO) . TNO adheres to the usual get/set bean standards. I have another object that acts as a manager for the TNO. Let's call it, “The Node Manager Object” (TNMO). TNMO has methods that will create and return TNO's, and will persist TNO's  into the database (with “add” and “remove” methods).

TNO actually ends up in another Object to act as it's reference to the tree structure so that Object doesn't have to worry about it's place in the tree.

Now, I can't have 2 different users manipulate the same Tree Structure at the same time. I can't have 1 person delete something while another person is moving a node in the tree. Otherwise the Nested Set model will go out of whack! I can't lock the table because I've got multiple trees in 1 table and that would cause the whole app to slow down while people are trying to access different trees. (It's ok to slow down access to one tree.)

So this is the code I've put together to lock access to 1 tree at a time.

(This is just sample code I've been working with as a proof of concept.)

The first JSP file that executes would create the 1 MO for the system to use and store it in the application scope.

  ManagerObject tnmo = new ManagerObject(TreeID); 
  application.setAttribute("tnmo", tnmo); 

Then when a page needed to access the tree (in the below case add a node), it would retrieve the TNMO out of the application scope and synchronize on it. Then perform the operation.

  ManagerObject gottenTNMO = (ManagerObject)application.getAttribute(“tnmo”);

      NodeObject tno = (NodeObject)gottenTNMO.createNodeObject(NodeID);

I've done a ghetto load test on my local machine by running the above JSP and another JSP that deletes instead of adds in a few web browsers that are set to refresh in less than a second. (I'll run a ton of them at the same time and just watch the DB crank away at adding/deleting nodes.)

Before I was synchronizing on the “gottenTNMO” object, my tree structure was getting out of whack. In the nested sets model each node has a left and right value. So when the left and right values of the nodes went out of alignment I knew everything was going wrong. But now that I'm using the synchronize block in the JSP's, everything  works fine.

(Like I said, this is just proof of concept code. I used it to check certain things such as being able to lock the TNMO. This code doesn't illustrate how I would be using these node objects in other objects to act as a reference to their place in a tree. But the concept of locking a “Manager” through synchronizing in JSP is what I'm asking about.)


Would this work in a clustered or load balanced environment? Right now I'm synchronizing on a object in memory. If this application is either load balanced or clustered, will this method of synchronizing still work?

Thank you for your time if you've read this far. I appreciate anyone who can shed some light on this question.

(I wrote this late at night so I hope its coherent!)

michael (
Wednesday, July 14, 2004

>Would this work in a clustered or load balanced environment?

I don't think so.  You're locking on an object in memory.  This lock is JVM specific, and can't affect anything in another JVM (as in a load balance situation).  Synchronized blocks are fine for protecting Java Objects (e.g. maintaining invariants).  But it's the db structure you're protecting, so you really need to lock at the db level.

Wednesday, July 14, 2004

I don't think nested sets will cluster, but if you stored the nodes/trees a different way, you could get what you want.

I like to give Zelda answers to questions.

Wednesday, July 14, 2004

Thanks guys.

I'll be looking into row level DB locking. I wanted to avoid that because obviously the DB has to support that, but it seems that I don't have a choice.

Thanks again.

michael (
Wednesday, July 14, 2004

Another thing you can try is putting your own lock data (unique identifier of "user"/thread/whatever having edit control) in the database, using the database structure to ensure there will only ever be [0,1] lock on a given item.

The advantage is portability, and being able to operate on minimalist databases.  The disadvantage is that lock acquisition isn't perfect.  There's a small possibility of two simultaneous users taking the lock, then only one of them actually has it.  Thus, one user will proceed normally, but the other will incorrectly think he has a lock, until he checks the database again before saving changes and finds that item unlocked or locked by someone else.  Really short version - you can't screw up the data, but you can annoy your users.

Since our system already had a number of failure cases (database unreachable, server unreachable, lock time out, lock manually expired by administrator) with the same consequences, and we have a fairly low probability of simultaneous edits, it works great.

Wednesday, July 14, 2004

Actually, I just did some research and I can't believe how easy it seems to be to implement row-level locking and transactions. I was a little afraid of them because I haven't used them (row level locking) before.

But after reading this:

And this:

It looks like a piece of cake.

michael (
Wednesday, July 14, 2004

*  Recent Topics

*  Fog Creek Home