Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Mailing Lists -> Oracle-L -> write consistency/read consistency
`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-lReceived on Mon Jun 26 2006 - 12:02:06 CDT
![]() |
![]() |