pragma autonomous_transaction in a trigger

Jaanna picture Jaanna · May 21, 2014 · Viewed 39.3k times · Source

I have written a trigger on one table which deletes data from other table upon a condition. The trigger has pragma autonomous_transaction, and trigger works as intended. However, I do wonder if there can be any problems in future, say if data is inserted by multiple users/sources at the same time etc...Any suggestions?

Source table t1:

--------------------------------------------
| user_id | auth_name1 | auth_name2 | data |
--------------------------------------------
|  1      |  Name1     |  Name2      | d1  |
|  2      |  Name3     |  Name4      | d2  |
|  3      |  Name5     |  Name1      | d3  |
--------------------------------------------

Target table t2:

   ------------------------------------------------
   | record_id |  identifier | status |   data1   |
   ------------------------------------------------
   |  100      |  Broken     |  11    |   Name1   |
   |  101      |  Reminder   |  99    |   Name1   |
   |  102      |  Broken     |  99    |   Name2   |
   |  103      |  Broken     |  11    |   Name4   |
   ------------------------------------------------

Trigger code:

create or replace trigger "ca"."t$t1"
    after update of auth_name1, auth_name2 on ca.t1  
    for each row
declare
    pragma autonomous_transaction;
begin
    if :new.auth_name1 is not null and :new.auth_name2 is not null then
         delete from ca.t2 ml
         where ml.identifier = 'Broken'
         and data1 = regexp_substr(:new.auth_name1, '\S+$')||' '||regexp_substr(:new.auth_name1, '^\S+')
         and status = 11;
         commit;
    end if;
end t$t1;

Answer

Justin Cave picture Justin Cave · May 21, 2014

Using an autonomous transaction for anything other than logging that you want to be preserved when the parent transaction rolls back is almost certainly an error. This is not a good use of an autonomous transaction.

What happens, for example, if I update a row in t1 but my transaction rolls back. The t2 changes have already been made and committed so they don't roll back. That generally means that the t2 data is now incorrect. The whole point of transactions is to ensure that a set of changes is atomic and is either completely successful or completely reverted. Allowing code to be partially successful is almost never a good idea.

I'm hard-pressed to see what using an autonomous transaction buys you here. You'll often see people incorrectly using autonomous transactions to incorrectly work around mutating trigger errors. But the code you posted wouldn't generate a mutating trigger error unless there was a row-level trigger on t2 that was also trying to update t1 or some similar mechanism that was introducing a mutating table. If that's the case, though, using an autonomous transaction is generally even worse because the autonomous transaction then cannot see the changes being made in the parent transaction which almost certainly causes the code to behave differently than you would desire.