触发器自治事务问题

n1986m 2010-01-07 08:15:43
触发器现在编译已经通过了,但是在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;
...全文
336 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
iqa001 2010-10-19
  • 打赏
  • 举报
回复
[Quote=引用楼主 n1986m 的回复:]
触发器现在编译已经通过了,但是在UPDATE AC30表AAE008字段的时候,触发下面的触发器,没有执行通过。
提示错误:deadlock detected while waiting for resource。等待资源的过程中发生死锁,想想也是啊,对于自治事务了解不深,高手帮忙看看如何处理啊。对操作自身表的时候触发器有没有其他的实现方式?
CREATE OR REPLACE TRIGGER……
[/Quote]
---------------
碰巧来到这里。
首先8楼的说法是正确的。
---按照楼主程序看,估计楼主的意思当AAE008的值有变化的时候要将AAE140的值设置为32。
那其实很简单,直接这样赋值就可以了:
:new.AAE140 := '32';
另外正如8楼说的insert里没有old值,因此如果一个要在insert时使用触发器设置
AAE140 的话,那要分开处理,用户 if inserting then……
n1986m 2010-01-17
  • 打赏
  • 举报
回复
最后都没解决!!!!
SambaGao 2010-01-14
  • 打赏
  • 举报
回复
关注
n1986m 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 qq646748739 的回复:]
引用楼主 n1986m 的回复:
触发器现在编译已经通过了,但是在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;


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

[/Quote]没猜错的话,没错!可实际上猜错了啊!而且一个事务不管是自治事务还是其他事物,都应该提交的,commit是没有错的,而且是必须的。
n1986m 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 huangyunzeng2008 的回复:]
一般情况下别这样写触发器,没有什么实际的意义,而且还容易死锁。你这个触发器有两个问题:
1,对应insert来说,根本没有old,因此对于insert而言,永远不会触发。
2。 既然update AAE008,肯定是要发生变化了,不然还update有什么意义呢!因此when没有必要写。
3。根本没有必要写触发器:只要执行一个update语句就足够了!
update AC30
set AAC008=‘’,aae010=‘’
where aac001=‘’
and  aae140=‘’;
引号中的值根据具体情况丰富。
[/Quote]前两条说的很正确啊,第三条我用触发器涉及到业务,这里不多说了就是必须得用触发器了
n1986m 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wildwave 的回复:]
试试
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;
[/Quote]本质没变啊
碧水幽幽泉 2010-01-09
  • 打赏
  • 举报
回复
[Quote=引用楼主 n1986m 的回复:]
触发器现在编译已经通过了,但是在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;

[/Quote]
问题很简单!去掉commit;
我没猜错的话!应该没错!
huangyunzeng2008 2010-01-09
  • 打赏
  • 举报
回复
一般情况下别这样写触发器,没有什么实际的意义,而且还容易死锁。你这个触发器有两个问题:
1,对应insert来说,根本没有old,因此对于insert而言,永远不会触发。
2。 既然update AAE008,肯定是要发生变化了,不然还update有什么意义呢!因此when没有必要写。
3。根本没有必要写触发器:只要执行一个update语句就足够了!
update AC30
set AAC008=‘’,aae010=‘’
where aac001=‘’
and aae140=‘’;
引号中的值根据具体情况丰富。
小灰狼W 2010-01-09
  • 打赏
  • 举报
回复
试试
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;
n1986m 2010-01-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mis6808 的回复:]
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;

[/Quote]
明明是一个行触发器,去掉那字段限制也没有什么现实性的修改啊
n1986m 2010-01-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 inthirties 的回复:]
只有if里的才commit

其他的条件下没有commit也没有rollback,所以导致问题。
[/Quote]没明白什么意思。如何修改呢?
n1986m 2010-01-08
  • 打赏
  • 举报
回复
[Quote=引用楼主 n1986m 的回复:]
触发器现在编译已经通过了,但是在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;

[/Quote]
我已经用了自治事务来控制了啊
耳海 2010-01-08
  • 打赏
  • 举报
回复
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;
inthirties 2010-01-08
  • 打赏
  • 举报
回复
只有if里的才commit

其他的条件下没有commit也没有rollback,所以导致问题。
wh62592855 2010-01-07
  • 打赏
  • 举报
回复
你前面的DML语句已经把该行数据锁住了
你在触发器里想再次更新这条数据?

不知道该怎么做 呵呵

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧