RE:Row Locking
Posted in 1997
This may be kind of late, as I caught this on Deja News. We had a problem
like you are talking about on a 3-tiered system using Informix as the
back end. Concurrency is about 800 - 1000 users. We implemented a
pseudo-locking scheme where an additional column was added to the table (
in this case, master ), and the default value was 'none'. When a user
needed to update the table, or any of it's child records, the presence of
the string 'none' in this column was checked, then his/her network logon
ID was placed in the column. Users hitting this row during an update
would get a message saying 'Record in use by Jane Doe'. ( this was done
by doing a lookup on the user id ) This application was for a major phone
company, and it works like a champ. I agree with Pablo, that row locking
is not necessary, and even when available, there are often better
application specific ways.
Dave Gallucci
/*********************************/
Ok. Here is an easy one. Only involves 2 tables (master and detail).
This is of course very simlified and I have not checked the syntax :-)
CREATE TABLE master (id INT PRIMARY KEY,
name VARCHAR(31),
address VARCHAR(21),
amount DECIMAL(16,4) );
CREATE INDEX x1 ON master (name);
CREATE INDEX x2 ON master (address);
CREATE TABLE detail (id INT REFERENCES master,
line_no INT,
item_no INT,
descr VARCHAR(100),
cost DECIMAL(10,4));
ALTER TABLE detail PRIMARY KEY(id, line_no);
Now what the app does is it allows users to select a record from the
master table, get all child records from the detail table and allow the
users to add/delete/modify those records as needed. After the user exits
it updates the
master table by selecting the sum of cost from the detail table. The sql
statements involved are something like this: (assume everything is under
transaction control)
-- We need to lock the master table so nobody else will update it while
we are.
SELECT * FROM master WHERE id = ? FOR UPDATE;
-- No need to lock the detail recs 'cause the master rec is locked.
SELECT * FROM detail WHERE id = ? ORDER BY line_no;
-- After the user exits we update all detail recs, probably by deleting
them first, and then inserting whatever the user has typed in.
-- Then we'll need to update the master table and release the lock.
UPDATE master SET amount = (SELECT sum(cost) FROM detail WHERE id = ?)
WHERE id = ?;
COMMIT;
If you have row level locking, the first select stmt will lock one row.
As the primary key is 4 bytes you can potentially put 4-500 keys on any
page (if you have 2K pages). In a page lock system (like Sybase and
MSSQL) the probability of a user trying to access one of the ~499 key
values another user has locked is pretty high.
Page lock workarounds could be:
1) Make the primary key >1Kb, so you would only have one key per page.
(Disks are cheap, right?)
2) Use optimistic locking. (So users who have been typing in for hours
get the message: Somebody else has modified this rec while you were
working. Please try again).
3) Swich to Informix :-)
Take care,
-Snorri
/*********************************/
-------------------==== Posted via Deja News ====-----------------------
http://www.dejanews.com/ Search, Read, Post to Usenet