Clinton
Clinton

Reputation: 23145

How to lock upon select, not just insert/update/delete

Lets say I've got code like the following:

begin
  select ... from T where x = 42;         -- (1)
  .
  .
  .
  update T ... where x = 42;              -- (2)
  commit;
end;

Am I correct in saying that by the time (2) executes, whatever has been selected from T in (1) may no longer be in T, if, for example, in another session the following executed:

delete from T where x = 42;

If so, what I would like to happen is the select statement to 'lock' T, so it can not be modified.

I realise I can do this explicitly by doing:

lock table T in exclusive mode;

But what if T is a view? Do I have to look through the definition of Ts view/subviews to find all tables it references and lock them individually, or can I do something like this:

begin
  START_TRANSACTION;
  select ... from T where x = 42;         -- (1)
  .
  .
  .
  update T ... where x = 42;              -- (2)
  commit;
end;

Where START_TRANSACTION ensures locks all tables referred to in all select statements until the transaction is complete?

Or is there another nicer solution to this issue? I'm using Oracle 10g if that is important.

Upvotes: 2

Views: 539

Answers (3)

paxdiablo
paxdiablo

Reputation: 882806

You need to use the select ... for update variation as shown here.

You definitely don't want to lock the entire table, although locking a view is valid. From the Oracle docs:

When a LOCK TABLE statement is issued on a view, the underlying base tables are locked.

However, that may be a performance killer and your DBAs will find you - there's nowhere to hide :-)

Upvotes: 2

cagcowboy
cagcowboy

Reputation: 30898

Am I correct in saying that by the time (2) executes, whatever has been selected from T in (1) may no longer be in T

Yes.

So you can lock the row by doing...

SELECT ...
[INTO   ...]
FROM   T
WHERE  x = 42
FOR    UPDATE [NOWAIT];

You can optionally use NOWAIT to make the statement fail if someone else already has the row locked. Without the NOWAIT the statement will pause until it can lock the row.

Upvotes: 5

Kurtis Nusbaum
Kurtis Nusbaum

Reputation: 30845

I'm pretty sure that transaction are exactly what you want here. The help enforce what's called ACID for a sequence of operations.

Upvotes: 0

Related Questions