Let us consider the program flow:
- You start a transaction.
- You perform a DML operation on your table.
- Your trigger fires and is an autonomous transaction so creates a separate transaction.
- Your original transaction continues.
- Maybe you perform additional DML actions in that original trasnsaction.
- One of those additional DML actions raises an exception.
- Your entire transaction (but not the separate autonomous transaction) is rolled back.
However:
- You started a separate autonomous transaction.
- That calls the stored procedure.
- Which does a number of DML statements.
- Then the trigger commits them.
You are left in a state where you have two transactions, the original one has been rolled back and the autonomous transaction has been committed.
If the autonomous transaction is used for logging and you want it to always document the actions whether the original transaction failed or was successful then this behaviour is fine.
If the autonomonous transaction is part of the normal business logic then you are potentially left in an inconsistent state where half the transaction was rolled back and half was committed; this is not what you want.
In the latter case, the normal solution would to be to remove the COMMIT
from the trigger and make it a non-autonomous transaction and then the DML resulting from the trigger will be part of the original transaction and will be committed (or rolled back) with that transaction.
This is the pseudo code of what I'm trying to do
proc1 (input) - program logic then insert into table X, commit.
proc2 (input) - program logic then insert into table Y, commit.
See: What is the effect of placing the commit after DML in procedure?
In general, you should NOT put a COMMIT
in a procedure so your pseudo-code should be:
proc1 (input) - program logic then insert into table X.
proc2 (input) - program logic then insert into table Y.
and your trigger should not be an autonomous transaction.
Then your program flow is:
- Insert into table A
- Trigger fires
- Depending on value, call
proc1
or proc2
.
- Complete the procedure.
- Complete the trigger.
- Complete the transaction and
COMMIT
(either from the code that performed the insert or automatically as the transaction closes).