Database Reference
In-Depth Information
Using optimistic locking
If you are doing lots of transactions which look like the following:
BEGIN;
SELECT * FROM ACCOUNTS WHERE HOLDER_NAME ='BOB' FOR UPDATE;
<do some calculations here>
UPDATE ACCOUNTS SET BALANCE = 42.00 WHERE HOLDER_NAME ='BOB';
COMMIT;
Then you may gain some performance by moving from explicit locking ( SELECT FOR
UPDATE ) to optimistic locking.
Optimistic locking assumes that others don't update the same record, and checks this at
update time, instead of locking the record for the time it takes to process the information on
the client side.
How to do it...
Rewrite your application so that the preceding transaction is transformed into something like
the following:
BEGIN;
SELECT A.*, (A.*::text) AS OLDACCINFO
FROM ACCOUNTS A WHERE HOLDER_NAME ='BOB';
<do some calculations here>
UPDATE ACCOUNTS SET BALANCE = 42.00
WHERE HOLDER_NAME ='BOB'
AND (A.*::text) = <OLDACCINFO from select above>;
COMMIT;
Then, check that the UPDATE did update one row in your application code. If it did not, then
the account for bob was modified between SELECT and UPDATE , and you probably need to
re-run your whole transaction.
How it works...
Instead of locking Bob's row for the time the data from select is processed in the client, it
queries the old state of Bob's account record in variable OLDACCINFO , and then uses this
value to check that the record has not changed.
You can also save all fields individually, and then check them all in UPDATE query, or if you
can have an automatic last_change field, then you can use this. Or, if you actually care only
about a few fields changing, such as BALANCE and can ignore others, say E_MAIL , then you
can only check the relevant fields in UPDATE .
 
Search WWH ::




Custom Search