Ask YC: How do you handle locking in your app?
A simple scenario:
At 1:00, Jane pulls a record into her browser: Lakeside High School, 123 Main St., 555-1111.
At 1:05, Fred pulls the same record into his browser.
At 1:06, Fred changes the address to 123 Oak St.
At 1:08, Mary changes the phone number to 555-2222.
Questions:
How to you handle the database locking?
- Pessimistic, lock the row at 1:00 and don't let Fred have it?
- Optimistic, let everyone take anything they want, but don't let Mary update?
- Column level locking?
- Special processing in you app?
How do you maintain state?
- Using sessions?
- Keeping a "before image" of the row? In the client? On the server? As a separate data base record?
I realize there is not one correct answer. Just curious how other YC'ers handle situations like this.
21 comments
[ 4.8 ms ] story [ 62.7 ms ] threadYes, the client could fake it, but such faking would not open up new capabilities that the client didn't already have.
Are you not too concerned about this because the real validation happens on the server anyway?
Suppose Al is in charge of color and Betty is in charge of size. They both get the form at the same time.
Al sends oldsize=M newsize=M oldcolor=green newcolor=blue
Betty sends oldsize=M newsize=S oldcolor=green newcolor=green
The server ignores Al's oldsize/newsize and Betty's oldcolor/newcolor because the values are unchanged.
You end up with size=S and color=blue no matter who sends the update first.
By "faking it" I refer to the fact that the old values are user-supplied data. Validation of the new data is a separate issue. Someone could "fake" an old value. This merely means they would change a value that they were already authorized to change. Messing with the "old" values on the client side has no hack value. That's why I'm not at all concerned about it.
pessimistic locking in general is really tricky
http://www.ibm.com/developerworks/websphere/techjournal/0603...
I forgot to add that if you're using a good framework, it typically already has a built-in mechanism for optimistic locking
Handling semi structured data (documents of some sort) is way trickier and depends a great deal on the particular data format and patterns of use. Merging is desirable but very hard to achieve in many cases.
One other thing that is worth thinking about is how the locking strategy scales. The most popular idea these days is to seperate read and write operations so all writes go to one DBMS server and the reads are distributed to replicas. That's ugly to integrate after the fact, so if you expect your app to grow fast you should probably design it like that from the start.
1) when Mary got the record,
2) whether she got the same record as Jane and Fred, and finally
3) whether Mary = Jane or not!8-))
[Hint: the example was not properly stated.]
It is practically impossible to maintain a useful, enforceable lock on a record in a web application, given the lack of a persistent connection between the client (browser) and the back end. So you are usually left with two choices:
1. Last one in wins: given that the two users presumably have good reasons for modifying the record in question, let them figure it out if there is a conflict. As long as updates are atomic, consistent, blah, blah this works best.
2. Versioning: Every record has a version number associated with it and the database rejects updates with a version != to what is in there.
The real trick is to set yourself up so that you have a single-writer for any given piece of data in the common case and defer whatever locking is necessary optimistically to the database.
IMO, this is the heart of the problem because it renders pessimistic (what we've used in the enterprise for years) virtually useless.
Fortunately, there are techniques to get around them. Several interesting lines of thought are presented in this thread. Thanks to all who posted them. You gave me quite a bit to think about.
http://worsethanfailure.com/Articles/I_Think_I_0x27_ll_Call_...