锁定 SQL 表

问题描述 投票:0回答:1

假设我有一个过程,它试图根据条件评估将记录逐一插入到单独的表中,并使用 sys_refcursor 我试图找出我们插入数据的表。

在该过程中,我们有 DML 和 DDL 命令,例如截断、插入、选择、创建游标。

假设多个用户尝试使用相同的参数调用该过程。

问题是,当多个用户尝试运行我们在其中截断最终插入和选择的同一个表的过程时,输出数据中可能会出现数据丢失或数据模糊的情况。

想知道,过程是否对过程体内提到的表加了锁。

现在要输出过程的结果集,我将行插入到该表名中并使用 sys_refcursor,我使用以下代码返回其内容:

open prc for select * from tablename;

假设我不想将行插入任何表中。我需要直接将结果集从 select 语句输出到输出变量。我们如何才能实现这一目标?

执行过程调用,对过程主体中提到的表加锁,以便其他用户无法访问这些表并修改它们。

伪代码:

create or replace PROCEDURE name(input varaibles, prc out SYS_REFCURSOR)
   IS 
        declare variables;
        cursor1 declaration;
        begin
             EXECUTE immediate 'TRUNCATE TABLE tablename';
             for i in cursor1
                 loop
                   insert into tablename select * from table1;
                 end loop;
        open prc for select * from tablename;
  end;
oracle stored-procedures plsql locking
1个回答
0
投票

我不明白你的程序的目的是什么,也许有更好的解决方案。但是...

  • 每个 DML 语句都经过优化并转换为某种“字节码”。 - 此“字节码”适用于数字数据段 ID,而不是纯表名。

  • TRUNCATE 是 DDL 语句。它丢弃表的数据段并分配一个新的数据段。为了截断表,不得有任何正在运行的游标,具体取决于表的库缓存对象。所以截断将等到allDML完成

  • 在截断和插入之间,其他会话可以截断同一个表。然后您将有两个会话插入同一个表中。

  • 虽然您有两个会话插入同一个表,但它们不会干扰。您不提交事务(截断除外 - DDL 始终提交)。因此每个会话的光标将仅返回自己的会话数据。

  • 注意:您的过程不会提交/回滚,因此任何连续的 TRUNCATE 都必须等到对您的过程的第一次调用决定如何处理自己的数据。

© www.soinside.com 2019 - 2024. All rights reserved.