如何锁定select,而不仅仅是插入/更新/删除

Cli*_*ton 2 sql database oracle locking

可以说我有以下代码:

begin
  select ... from T where x = 42;         -- (1)
  .
  .
  .
  update T ... where x = 42;              -- (2)
  commit;
end;
Run Code Online (Sandbox Code Playgroud)

我是否正确地说,在时间(2)执行时,从(1)中的T中选择的任何内容可能不再在T中,例如,如果在另一个会话中执行以下操作:

delete from T where x = 42;
Run Code Online (Sandbox Code Playgroud)

如果是这样,我想要发生的是"锁定"的select语句T,因此无法修改.

我意识到我可以通过以下方式明确地做到:

lock table T in exclusive mode;
Run Code Online (Sandbox Code Playgroud)

但如果T是一种观点呢?我是否必须查看Ts视图/子视图的定义以查找它引用的所有表并单独锁定它们,或者我可以执行以下操作:

begin
  START_TRANSACTION;
  select ... from T where x = 42;         -- (1)
  .
  .
  .
  update T ... where x = 42;              -- (2)
  commit;
end;
Run Code Online (Sandbox Code Playgroud)

Where START_TRANSACTION确保锁定所有select语句中引用的所有表,直到事务完成为止?

或者是否有另一个更好的解决方案?如果这很重要,我正在使用Oracle 10g.

cag*_*boy 5

我是否正确地说,到时间(2)执行时,从(1)中的T中选择的任何内容可能不再在T中

是.

所以你可以通过这样做来锁定行...

SELECT ...
[INTO   ...]
FROM   T
WHERE  x = 42
FOR    UPDATE [NOWAIT];
Run Code Online (Sandbox Code Playgroud)

如果其他人已经锁定了行,您可以选择使用NOWAIT使语句失败.如果没有NOWAIT,语句将暂停,直到它可以锁定行.