是否可以锁定限制从其他会话读取的表?我会更喜欢“你可以用......解决它”这样的建议,而不是“你为什么需要那个?”。
1 回答
至少你承认这是一个奇怪的要求。
您可以做一些事情来实现这一点。所有这些都需要一些重定向,这意味着表必须由一个单独的模式拥有,而不是用户连接的那个。这是因为 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 实现了多版本并发模型,这意味着我们始终可以读取表,而不管其他人是否在使用该表。面对这种方法,您想做的事情会发生。