ORA-02241: Must COMMIT or ROLLBACK Pending Transaction
ORA-02241 occurs when you attempt to execute certain session-altering commands or DDL statements while an uncommitted (pending) transaction exists in your current session. Oracle enforces explicit transaction closure before allowing operations like SET ROLE or specific ALTER SESSION commands, ensuring data integrity and consistency. This error is a safeguard, not a bug — Oracle is simply telling you to clean up your transaction before changing session context.
Top 3 Causes
1. Uncommitted DML Before ALTER SESSION or DDL
The most common cause is executing DML (INSERT, UPDATE, DELETE) and then attempting a session-level change without committing or rolling back first.
-- Problematic sequence
UPDATE employees SET salary = salary * 1.1 WHERE department_id = 20;
-- ORA-02241 may fire here if session context change is required
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
-- Fixed sequence
UPDATE employees SET salary = salary * 1.1 WHERE department_id = 20;
COMMIT; -- Explicitly close the transaction
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
2. SET ROLE with an Active Transaction
SET ROLE changes the privilege context of a session and requires no pending transactions at the time of execution.
-- Wrong approach
INSERT INTO audit_log (log_time, action) VALUES (SYSDATE, 'ROLE_CHANGE');
SET ROLE app_admin_role; -- ORA-02241 fires here
-- Correct approach
INSERT INTO audit_log (log_time, action) VALUES (SYSDATE, 'ROLE_CHANGE');
COMMIT;
SET ROLE app_admin_role;
-- Disable all roles safely
COMMIT;
SET ROLE NONE;
3. Distributed Transactions / DB Links
In distributed environments using database links, transaction boundaries are often unclear, leading developers to unknowingly leave transactions open before issuing session commands.
-- Insert via DB Link
INSERT INTO orders@remote_db (order_id, amount)
VALUES (1001, 500.00);
-- Always commit before any session-level operation
COMMIT;
-- Check for pending distributed transactions
SELECT local_tran_id, global_tran_id, state
FROM dba_2pc_pending;
-- Force commit a stuck distributed transaction (DBA only)
-- COMMIT FORCE 'local_tran_id_value';
Quick Fix Solutions
Check if an active transaction exists in your session:
SELECT s.sid,
s.serial#,
s.username,
t.status,
t.start_time
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE s.sid = SYS_CONTEXT('USERENV', 'SID');
If rows are returned, a pending transaction exists. Simply run:
COMMIT;
-- or
ROLLBACK;
Then retry your original command.
Prevention Tips
1. Always define explicit transaction boundaries in code.
Never rely on implicit commits from DDL when mixing DML and session commands. Treat every INSERT, UPDATE, or DELETE block as a transaction unit that must end with COMMIT or ROLLBACK before any session-altering operation.
-- Good practice pattern
BEGIN
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
/
2. Monitor long-running active transactions proactively.
Add the following query to your DBA monitoring routine to catch sessions holding open transactions for too long — these are prime candidates for ORA-02241 if a role change or session command is attempted:
SELECT s.sid,
s.username,
s.machine,
ROUND((SYSDATE - CAST(TO_DATE(t.start_time,
'MM/DD/YY HH24:MI:SS') AS DATE)) * 24 * 60, 2)
AS minutes_active
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE - CAST(TO_DATE(t.start_time,
'MM/DD/YY HH24:MI:SS') AS DATE)) * 24 * 60 > 5
ORDER BY minutes_active DESC;
Related Errors
-
ORA-01453 —
SET TRANSACTIONnot the first statement; similar transaction ordering issue. - ORA-02089 — COMMIT not allowed in a subordinate distributed session; often appears alongside ORA-02241 in DB Link scenarios.
- ORA-00060 — Deadlock detected; indirectly related when multiple sessions hold unresolved transactions.
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)