2015-04-22 58 views
1

我有一个主存储过程,它调用多个存储过程在一次去9到10个多个表上写数据。一旦所有插入完成,所有插入都会有一个提交。
我想用数据并发性和对各子过程锁表,它们没有任何承诺,所以如何在oracle中明确地解锁锁定表

LOCK TABLE表名IN LOCK_MODE

将工作,但将持有该表直到其余的数据被插入在这之后调用的各个表中,并且最终的提交或回滚被调用,这不是一个好主意。我也没有打开dbms_lock

将锁定我的主存储过程中的所有表,或锁定在各自的子存储过程中的表是唯一的选择?

我的主存储过程是这样的

PROCEDURE POPULATE_ALL(P_ASOFDATE DATE, P_ENTITY VARCHAR2) IS 
    BEGIN 
     POPULATE_ABC_BOOK(P_ASOFDATE); 
     POPULATE_XYZ(P_ASOFDATE, P_ENTITY); 
     POPULATE_DEF(P_ASOFDATE, P_ENTITY); 
     POPULATE_AAA(P_ASOFDATE, P_ENTITY); 
    commit; 
    EXCEPTION 
    WHEN OTHERS THEN 
     rollback; 
     P_ERROR := SQLERRM; 
     RAISE_APPLICATION_ERROR(-20001, 
           '*** Unexpected Error in POPULATE_ALL -->' || 
           P_ERROR); 
    END POPULATE_ALL; 

其中POPULATE_XYZ被填充XYZ表。

+2

为什么你明确地锁定表在第一个地方?我已经处理了很多Oracle系统,而且我还没有看到明确表锁定有用的地方。你有什么意思让'dbms_lock'“打开”?你是说因为某种原因你不允许使用'dbms_lock'吗?为什么你会被允许显式锁定一个表,但不能获取用户定义的锁? –

+0

是的,我不允许使用'dbms_lock' – deejay

+0

为什么你明确地锁定表格?为什么你会被允许显式锁定一个表,但不能获取用户定义的锁? –

回答

0

看起来你根本不需要锁定。只要做你的插入没有任何明确的锁定。

在事务处理过程中无法解锁表。这个操作在Oracle中没有任何意义;它只有在数据库支持脏读时才有用。表锁结束只有

  • 承诺,
  • 回滚或
  • 回滚到保存点锁建立
  • 执行

之前。

+0

考虑场景...事务T1更改表ABC并将行值插入123 ...第二个事务T2进入,而T1仍在工作。 T2变为789.T1承诺,一切都很好。 T2发生异常并回滚。但是由于T2将该值更改为789并且T1已提交。表ABC,123或789中的值是多少?如果它的789,那么数据会是错误的。请解释 – deejay

+0

@deejay - 我没有关注。如果T1尚未提交插入,则T2无法看到该行(未提交),因此直到T1提交后才能更新它,因为直到此时才能看到该行。 –

+0

@deejay,你有没有听过[ACID](https://en.wikipedia.org/wiki/ACID)? :)你可以尝试重现这种情况,你会发现它是不可能的。事务T2在提交T1之前没有机会更新'行值'。 –