当该用户(被授权者)拥有需要这些特权的持续交易时(显然,当用户(被授权者)发出他的交易时,他具有这些特权)我是'm curious about this. What happens if the DBA (or a grantor) revokes a user'(受让人)的特权 .
一个简单的场景使这更具体:用户A授予用户B权限,以便将数据插入到他的(用户A)架构中的表(例如Table1)中 . 用户B继续并发出一个进行大量插入的事务 . 当插入进行时,用户A撤销B的插入权限 . 请问:
1.用户B 's transaction fail midway with an automatic rollback performed on Table1 (I' m假设这是"abnormally terminated"进程的一个例子 - 一个conditions for a rollback;是吗?)?如果是,数据完整性如何处理?例如,Oracle是否保证插入不会在连续的中间停止?
2.用户B 's transaction complete before his privileges are taken away (meaning he can' t之后再进行插入)?
从逻辑上讲,我猜它已经是2但我在Oracle文档中找不到任何确认信息的信息 .
谢谢 .
EDIT: 添加一些我编写的PL / SQL代码来测试这个(我只是将它拼凑在一起测试这个场景 . 我不知道PL / SQL所以请纠正我,如果我错了) .
/* Start by testing select privileges */
set serveroutput on;
declare v_emp HR.tempemp%rowtype;
begin
dbms_output.enable(300000);
for count_var in 1..200000 loop -- loop a large number of times, and BEFORE the loop exits,
-- revoke the permissions manually from the grantor's session
select * into v_emp
from HR.tempemp
where employee_id = 100;
dbms_output.put_line(count_var||' '||v_emp.employee_id); -- print count_var so we know which iteration we're in
end loop;
end;
/* Now test insert privileges */
set serveroutput on;
begin
dbms_output.enable(300000);
for count_var in 1..20000000 loop -- loop a large number of times, and BEFORE the loop exits,
-- revoke the permissions manually from the grantor's session
insert into HR.tempemp
values(100);
dbms_output.put_line(count_var); -- print count_var so we know which iteration we're in
end loop;
end;
Observations:
1.一旦撤销生效, for
循环就会失效 . 因此,正如Dave所说,每次执行语句时都会检查权限 .
2.对于测试的插入部分,一旦 for
循环中途失败,在被授权者的会话中都不会看到任何插入(甚至是 for
所经历的插入) .
2 回答
我刚用以下场景对此进行了测试,这是发生的事情:
1-User A创建一个表 .
2-User A授予用户B插入权限 .
3用户B插入一行,但不执行COMMIT .
4-User A从用户B撤销 .
5用户B插入一行 but fails .
5用户B成功提交 .
这很容易测试:在模式A中创建空表 . 向模式B授予插入权限 . 在模式B中,启动长时间运行的INSERT语句 . 在它运行时,撤消插入权限 .
如果执行此操作,您将看到插入继续运行并成功完成 . 然后,如果您立即尝试再次执行它,您将获得
ORA-01031: insufficient privileges
. 所以很明显,Oracle会为每个语句执行检查一次权限 . 我浏览了一些文档,并没有看到任何直接说明的内容,但它似乎是最合乎逻辑的方法,实验支持它 .您询问:
“Oracle是否保证插入不会在连续的中间停止?”
如上所示,这在撤销特权的情况下并不真正相关;但是,如果在处理语句的过程中发生错误,Oracle似乎更值得解释一下Oracle的行为 . 除了Oracle中的错误之外,不可能插入部分行并在发生错误时留下 . 如果在处理单个SQL语句的过程中发生任何错误,那么该语句(而不是事务)到目前为止所做的更改将由Oracle在内部回滚 . 例如,如果要插入许多行并且数据段需要扩展但没有可用空间,则当前语句到目前为止完成的工作将被回滚,然后将错误返回给执行该语句的代码 . 这不是你引用的另一个帖子中讨论的"abnormally terminated process";进程继续运行并确定如何处理错误 - 它可以选择回滚整个事务,但没有义务这样做 .