Re: Mutating triggers & autonomous transactions

From: <roelof.streekstra_at_gmail.com>
Date: Wed, 22 Apr 2009 15:23:40 -0700 (PDT)
Message-ID: <65bf751e-82d2-4372-868f-15e2816fd3cd_at_g19g2000yql.googlegroups.com>



On Apr 22, 4:16 pm, Shakespeare <what..._at_xs4all.nl> wrote:
> roelof.streeks..._at_gmail.com schreef:
>
> > Hi all,
>
> > I have an application that uses the pragma autonomous transactions
> > inside trigger code to prevent the mutating triggers problem.
> > I do not think you can use pragma autonomous transactions do this.
> > Because an autonomous transactions is a new transaction with a new
> > SCN.
> > To me oracle will execute the blow code like this:
>
> > Step 1 Create new orderline get SCN
> > Step 2 trigger fires
> > Step 3 inside trigger call function
> > Step 4 function is autonomous ei get second SCN
>
> > In my opinion time has elapsed between step 1 and step 4 so some other
> > Process Could have gotten in between in those steps and change the
> > data
> > in the underlying tables.
>
> > I think if you have this problem of mutating tables you solve it by
> > creating
> > Three triggers on the underlying table.
> >    Trigger one is a before statement trigger to cleans out a temp
> >    Table that stores the changed records of the table you are
> > changing.
> >    Trigger Two is a after row trigger that fills up the temp table
> >    With change records.
> >    Trigger three is a after statement trigger that does the work of
> >    Calculating the total price of the order by using the temp table
> >    and the underlying transactional table.
>
> > If you do the three trigger approach you never have two SCN’s so you
> > do
> > not have any problems with your read consistency ever.
>
> > Is my reasoning true/valid?
>
> > This approach of three triggers a learned longtime ago when oracle was
> > still in the 7 series.
>
> > Thanks Roelof
>
> > PS I think that triggers should only be used for auditing and for
> > implementing certain kind of check constraints.
>
> > Current Code pattern is like this:
> >     table Order_header ( id, cust#, TotalOrderAmount)
> >     table Order_line (id,order_header_id,product_name,price)
> >     trigger on T1 before row on delete, update, insert called T1_BRDUI
> >     function CalcTotalOrderAmount( p_order_header_id)
>
> > trigger body T1_BRDUI
> > begin
> > ....
> >    UPDATE Order_header SET TotalOrderAmount=CalcTotalOrderAmount( NVL
> > (:new.order_header_id,:old.order_header_id)
> > WHERE id=NVL(:new.order_header_id,:old.order_header_id);
> > ...
> > end;
>
> > Function code:
> > FUNCTION CalcTotalOrderAmount( p_ order_header_id IN NUMBER)
> >   RETURN NUMBER
> > IS
> >   RETVAL   NUMBER;
> >   PRAGMA AUTONOMOUS_TRANSACTION;
> > BEGIN
> >   SELECT SUM(price)
> >     INTO RETVAL
> >     FROM Order_line
> >    WHERE order_header_id = p_order_header_id;
>
> >   RETURN retval;
> > END CalcTotalOrderAmount;
>
> > My solution would be
>
> I think you're right about this.
>
> But it looks like something is missing at the end of your post.
> If this is all about a total order amount, then this can be done more
> simply. Just add the amount of an inserted row to the total; you don't
> have to recalc the total every time. So you don't need to sum the detail
> records to calculate the total. So you won't have a mutating table
> problem at all.
> Same can be done with updates and deletes. It's all a matter of good
> book keeping.
>
> An other option might be (not sure about that): lock the order header
> row before updating and calculating the total of the details. A second
> process can not get this lock so will not fire in the period you mentioned.
>
> Shakespeare

I understand what you say here but my question is can you use

   autonomous transactions
in triggers to prevent the mutating table problem. Received on Wed Apr 22 2009 - 17:23:40 CDT

Original text of this message