Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Mailing Lists -> Oracle-L -> write consistency/read consistency

write consistency/read consistency

From: Henry Poras <henry_at_itasoftware.com>
Date: Mon, 26 Jun 2006 13:02:06 -0400
Message-ID: <000101c69942$42c89250$3800040a@itasoftware.com>


`I am trying to do an UPDATE in table_a based on the result of a query on table_b. For example, update my order (in table_a) if there is inventory in stock (in table_b). We can always do this using something along the lines of:

UPDATE table_a
SET number_ordered = number_ordered+1
WHERE EXISTS (
  SELECT 'x'
  FROM table_a, table_b
  WHERE <condition to check table_b for inventory for my order>

                         )

This looks like it should be nice and consistent. Everything in one SQL statement. But as has been pointed out to me, it isn't.

Follow this timeline:
Session A blocks a record in table_a
Session B starts the update (time 1). It is blocked by session A Session C updates table_b, changing the result of my nested query (time 2) Session A commits/rollback (doesn't matter) Session B finishes the update using the query result from time 1 which is no longer valid (the inventory is actually gone)

This is a bit different from the 'write consisntency' case discussed by Tom Kyte
http://tkyte.blogspot.com/2005/08/something-different-part-i-of-iii.html

In his example, the data changed by session C is in table_a, the table being updated. In this case, the SELECT is read consistent to the point in time when the query began. The update then does a current read on the returned records prior to doing the update. If anything has changed, the statement rolls back and begins again from a new point in time. In Tom's example, data in table_a has changed. In my example, it hasn't.

Here, the query returns a result set based on table_a and table_b. However, when table_b is modified, which would change the result set, this is never noticed as the query is not rerun. The curent reads of the table_a remain unchanged, and so the update completes when the lock is removed.

Is the only way to do this to break the statement up into multiple pieces and use SELECT FOR UPDATE?

Henry

--
http://www.freelists.org/webpage/oracle-l
Received on Mon Jun 26 2006 - 12:02:06 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US