我很好奇。如果DBA(或授权者)撤销用户(被授予者)的权限,而该用户(被授权者)具有需要这些权限的持续事务(显然,当用户(被授予者)发布其事务时)会发生什么情况,他有这些特权。)
使这更具体的一个简单方案:用户A授予用户B权限,以便将数据插入到他的(用户A)架构中的表(例如Table1)中。用户B继续并发出一个进行大量插入的事务。 当插入正在进行时,用户A撤销B的插入权限。作用:
逻辑上,我猜它已经是2但我在Oracle文档中找不到任何确认信息的信息。
感谢。
编辑:添加我编写的一些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;
观察:
for
循环就会失效。因此,正如Dave所说,每次执行声明时都会检查权限
2.对于测试的插入部分,一旦for
循环中途失败, none 插入(甚至不是 {{1在受让人的会话中可以看到经过。
答案 0 :(得分:1)
我刚用以下场景对此进行了测试,以下是发生的事情:
1-User A创建一个表。
2-User A授予用户B插入。
3-User B插入一行,但不执行COMMIT。
4-User A从用户B撤销。
5用户B插入一行但未通过。
5-User B成功提交。
答案 1 :(得分:1)
这很容易测试:在模式A中创建空表。为模式B授予插入权限。在模式B中,启动长时间运行的INSERT语句。在它运行时,撤消插入权限。
如果执行此操作,您将看到插入继续运行并成功完成。然后,如果您立即尝试再次执行它,您将获得ORA-01031: insufficient privileges
。所以很明显,Oracle会为每个语句执行检查一次权限。我浏览了一些文档并没有看到任何直接说明的内容,但它似乎是最合乎逻辑的方法而且实验支持它。
你问:
“Oracle是否保证插入不会在连续的中间停止?”
如上所示,这在撤销特权的情况下并不真正相关;但是,如果在处理语句的过程中发生错误,Oracle似乎更值得解释一下Oracle的行为。除了Oracle中的错误之外,不可能插入部分行并在发生错误时留下。如果在处理单个SQL语句的过程中发生任何错误,那么到目前为止由语句(而不是事务)所做的更改将由Oracle在内部回滚。例如,如果要插入许多行并且数据段需要扩展但没有可用空间,则当前语句到目前为止完成的工作将被回滚,然后将错误返回给执行该语句的代码。这不是您引用的其他主题中讨论的“异常终止的进程”;该过程继续运行并确定如何处理错误 - 它可以选择回滚整个事务,但没有义务这样做。