触发器现在编译已经通过了,但是在UPDATE AC30表AAE008字段的时候,触发下面的触发器,没有执行通过。
提示错误:deadlock detected while waiting for resource。等待资源的过程中发生死锁,想想也是啊,对于自治事务了解不深,高手帮忙看看如何处理啊。对操作自身表的时候触发器有没有其他的实现方式?
CREATE OR REPLACE TRIGGER trig_ac30_AAE008
  AFTER insert or update of  AAE008
  ON AC30
  FOR EACH ROW 
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  if (:NEW.AAE008 <> :OLD.AAE008) then
    UPDATE ac30       SET AAE008 = :NEW.AAE008, aae010 = :NEW.aae010
     WHERE AAC001 = :NEW.AAC001
       AND AAE140 = '32';
    COMMIT;
  end if;
END;

解决方案 »

  1.   

    你前面的DML语句已经把该行数据锁住了
    你在触发器里想再次更新这条数据?不知道该怎么做 呵呵
      

  2.   

    只有if里的才commit其他的条件下没有commit也没有rollback,所以导致问题。
      

  3.   

    CREATE OR REPLACE TRIGGER trig_ac30_AAE008 
      AFTER insert or update ON AC30 FOR EACH ROW 
    DECLARE 
      PRAGMA AUTONOMOUS_TRANSACTION; 
    BEGIN 
      if (:NEW.AAE008 <> :OLD.AAE008) then 
        UPDATE ac30       SET AAE008 = :NEW.AAE008, aae010 = :NEW.aae010 
        WHERE AAC001 = :NEW.AAC001 
          AND AAE140 = '32'; 
        COMMIT; 
      end if; 
    END; 
      

  4.   

    试试
    CREATE OR REPLACE TRIGGER trig_ac30_AAE008 
      AFTER insert or update of  AAE008 
      ON AC30 
      FOR EACH ROW when (NEW.AAE008 <> OLD.AAE008)
    DECLARE 
      PRAGMA AUTONOMOUS_TRANSACTION; 
    BEGIN 
        UPDATE ac30       SET AAE008 = :NEW.AAE008, aae010 = :NEW.aae010 
        WHERE AAC001 = :NEW.AAC001 
          AND AAE140 = '32'; 
        COMMIT; 
    END; 
      

  5.   

    一般情况下别这样写触发器,没有什么实际的意义,而且还容易死锁。你这个触发器有两个问题:
    1,对应insert来说,根本没有old,因此对于insert而言,永远不会触发。
    2。 既然update AAE008,肯定是要发生变化了,不然还update有什么意义呢!因此when没有必要写。
    3。根本没有必要写触发器:只要执行一个update语句就足够了!
     update AC30
     set AAC008=‘’,aae010=‘’
     where aac001=‘’
     and   aae140=‘’;
     引号中的值根据具体情况丰富。
      

  6.   

         问题很简单!去掉commit;
          我没猜错的话!应该没错!
      

  7.   

    没猜错的话,没错!可实际上猜错了啊!而且一个事务不管是自治事务还是其他事物,都应该提交的,commit是没有错的,而且是必须的。
      

  8.   

    ---------------
    碰巧来到这里。
    首先8楼的说法是正确的。
    ---按照楼主程序看,估计楼主的意思当AAE008的值有变化的时候要将AAE140的值设置为32。
    那其实很简单,直接这样赋值就可以了:
    :new.AAE140 := '32';
    另外正如8楼说的insert里没有old值,因此如果一个要在insert时使用触发器设置
    AAE140 的话,那要分开处理,用户 if inserting then……