Calling COMMIT or ROLLBACK from within a trigger will lead to an ORA-04092 exception, unless the trigger has
its own autonomous transaction.
Noncompliant code example
SET SERVEROUTPUT ON
CREATE TABLE accounts(
  balance NUMBER
);
INSERT INTO accounts VALUES(0);
CREATE TABLE log(
  message VARCHAR2(100)
);
CREATE TRIGGER beforeLogger
  BEFORE UPDATE ON accounts
  FOR EACH ROW
BEGIN
  INSERT INTO log VALUES('Attempt to update the value from ' || :OLD.balance || ' to ' || :NEW.balance);
  COMMIT; -- Noncompliant, will fail with a ORA-04092
END;
/
-- We want to be able to log any attempt to update the "accounts" table
BEGIN
  UPDATE accounts SET balance = 100;
  ROLLBACK; -- Ultimately, this update is rolled back, however we still want to log it
END;
/
SELECT * FROM log;
DROP TRIGGER beforeLogger;
DROP TABLE log;
DROP TABLE accounts;
Compliant solution
SET SERVEROUTPUT ON
CREATE TABLE accounts(
  balance NUMBER
);
INSERT INTO accounts VALUES(0);
CREATE TABLE log(
  message VARCHAR2(100)
);
CREATE TRIGGER beforeLogger
  BEFORE UPDATE ON accounts
  FOR EACH ROW
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO log VALUES('Attempt to update the value from ' || :OLD.balance || ' to ' || :NEW.balance);
  COMMIT; -- Compliant, commits the trigger's autonomous transaction, not the main one
END;
/
-- We want to be able to log any attempt to update the "accounts" table
BEGIN
  UPDATE accounts SET balance = 100;
  ROLLBACK; -- Ultimately, this update is rolled back, however we still want to log it
END;
/
SELECT * FROM log;
DROP TRIGGER beforeLogger;
DROP TABLE log;
DROP TABLE accounts;