撤销Oracle中的权限会影响使用这些权限的正在进行的事务吗?

时间:2011-04-06 11:10:17

标签: sql oracle transactions

我很好奇。如果DBA(或授权者)撤销用户(被授予者)的权限,而该用户(被授权者)具有需要这些权限的持续事务(显然,当用户(被授予者)发布其事务时)会发生什么情况,他有这些特权。)

使这更具体的一个简单方案:用户A授予用户B权限,以便将数据插入到他的(用户A)架构中的表(例如Table1)中。用户B继续并发出一个进行大量插入的事务。 当插入正在进行时,用户A撤销B的插入权限。作用:

    1.用户B的事务中途失败并在Table1上执行自动回滚(我假设这是“异常终止”过程的一个例子 - conditions for a rollback之一;是吗?)?如果是,数据完整性如何处理?例如,Oracle是否保证插入不会在连续的中间停止? 2.用户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;
    

    观察:

      1.一旦撤销生效,for循环就会失效。因此,正如Dave所说,每次执行声明时都会检查权限 2.对于测试的插入部分,一旦for循环中途失败, none 插入(甚至不是 {{1在受让人的会话中可以看到经过

2 个答案:

答案 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在内部回滚。例如,如果要插入许多行并且数据段需要扩展但没有可用空间,则当前语句到目前为止完成的工作将被回滚,然后将错误返回给执行该语句的代码。这不是您引用的其他主题中讨论的“异常终止的进程”;该过程继续运行并确定如何处理错误 - 它可以选择回滚整个事务,但没有义务这样做。