如何锁定表限制其他会话的读取?

时间:2012-11-03 08:07:28

标签: oracle plsql locking

是否可以锁定限制其他会话读取的表?我会更感谢像“你可以解决它......”这样的建议,而不是“为什么你需要它?”。

1 个答案:

答案 0 :(得分:4)

至少你承认这是一个奇怪的要求。

您可以采取一些措施来实现这一目标。所有这些都需要一些重定向,这意味着该表必须由一个单独的模式拥有,而不是用户连接的模式。这是因为Oracle没有阻止读取的机制,并且架构所有者始终可以访问其表;我们所能做的就是拒绝其他用户访问我们的表格。

一种选择是使用视图。大部分时间它指向你的桌子。

create or replace view public_user.your_table 
    as select * from private_user.your_table;

但是当你想拒绝访问时,你将它切换到另一个空表(显然必须与YOUR_TABLE具有相同的投影)。

create or replace view public_user.your_table 
    as select * from private_user.empty_table;

然后,当你完成后,你可以再次运行第一个语句。

这种方法相对简单但需要发布DDL。这意味着在YOUR_TABLE上工作的帐户也必须拥有PUBLIC_USER.YOUR_TABLE的权限。此外,发出DDL将使对表(视图)具有依赖性的对象无效。

所以这是另一种方法。

create table lock_table (col1 number not null);
insert into lock_table values (1);

create procedure lock_your_table as
    pragma autonomous_transaction;
begin
     update lock_table set col1 = 0;
     commit;
end;
create procedure unlock_your_table as
    pragma autonomous_transaction;
begin
     update lock_table set col1 = 1;
     commit;
end;

我们有不同版本的视图:

create or replace view public_user.your_table 
    as select * from private_user.your_table
                cross join lock_table
        where col1 = 1;

这将返回YOUR_TABLE中的所有行,或者返回所有行或它们,具体取决于LOCK_TABLE.COL1的值。因此,您撤消对运行lock_the_table()的表格数据的访问权限,并授予其运行unlock_the_table()


为什么Oracle会让它如此难以成为现实?因为它使应用程序用户感到困惑。 Oracle已经实现了一个多版本的并发模型,这意味着我们总是可以读取表,无论其他人是否正在使用该表。你想做的事情面对这种方法。