如何锁定选择,而不仅仅是插入/更新/删除
可以说我有如下代码:
begin
select ... from T where x = 42; -- (1)
.
.
.
update T ... where x = 42; -- (2)
commit;
end;
我是否正确地说,到 (2) 执行时,在 (1) 中从 T 中选择的任何内容可能不再在 T 中,例如,如果在另一个会话中执行以下内容:
delete from T where x = 42;
如果是这样,我希望发生的情况是将 select 语句“锁定”T
,因此无法对其进行修改。
我意识到我可以通过以下方式显式地做到这一点:
lock table T in exclusive mode;
但是如果 T
是一个视图呢?我是否必须查看 T
视图/子视图的定义才能找到它引用的所有表并单独锁定它们,或者我可以执行以下操作:
begin
START_TRANSACTION;
select ... from T where x = 42; -- (1)
.
.
.
update T ... where x = 42; -- (2)
commit;
end;
其中 START_TRANSACTION
确保锁定所有 select 语句中引用的所有表,直到事务完成?
或者这个问题还有其他更好的解决方案吗?如果这很重要的话,我正在使用 Oracle 10g。
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 T
s 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
。
因此,您可以通过执行以下操作来锁定行...
如果其他人已经锁定了该行,您可以选择使用 NOWAIT 使语句失败。如果没有NOWAIT,语句将暂停,直到它可以锁定该行。
Yes.
So you can lock the row by doing...
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.
您需要使用
select ... for update
变体,如图 此处。尽管锁定视图是有效的,但您绝对不想想要锁定整个表。来自 Oracle 文档:
然而,这可能会成为性能杀手,您的 DBA会找到您 - 无处可藏:-)
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:
However, that may be a performance killer and your DBAs will find you - there's nowhere to hide :-)
我很确定该交易正是您想要的。该帮助强制执行一系列操作的 ACID。
I'm pretty sure that transaction are exactly what you want here. The help enforce what's called ACID for a sequence of operations.