1

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

4

1 回答 1

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 中的所有行或 none 或它们,具体取决于 LOCK_TABLE.COL1 的值。因此,您撤销对您运行的表数据的访问权限lock_the_table()并授予它您运行的权限unlock_the_table()


为什么甲骨文很难做到这一点?因为它使应用程序用户感到困惑。Oracle 实现了多版本并发模型,这意味着我们始终可以读取表,而不管其他人是否在使用该表。面对这种方法,您想做的事情会发生。

于 2012-11-03T09:21:27.370 回答