是否可以锁定限制其他会话读取的表?我会更感谢像“你可以解决它......”这样的建议,而不是“为什么你需要它?”。
答案 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已经实现了一个多版本的并发模型,这意味着我们总是可以读取表,无论其他人是否正在使用该表。你想做的事情面对这种方法。