Well last week I came across this ORA-01591 while running alter command against one of the Oracle DB schema. It simply failed by giving following error.
SQL Error: ORA-01591: lock held by in-doubt distributed
transaction 5.4.426183
01591. 00000 - "lock held by in-doubt distributed transaction %s"
*Cause: Trying to access resource that is locked by a dead two-phase commit
transaction that is in prepared state.
*Action: DBA should query the pending_trans$ and related tables, and attempt
to repair network connection(s) to coordinator and commit point.
If timely repair is not possible, DBA should contact DBA at commit
point if known or end user for correct outcome, or use heuristic
default if given to issue a heuristic commit or abort command to
finalize the local portion of the distributed transaction.
01591. 00000 - "lock held by in-doubt distributed transaction %s"
*Cause: Trying to access resource that is locked by a dead two-phase commit
transaction that is in prepared state.
*Action: DBA should query the pending_trans$ and related tables, and attempt
to repair network connection(s) to coordinator and commit point.
If timely repair is not possible, DBA should contact DBA at commit
point if known or end user for correct outcome, or use heuristic
default if given to issue a heuristic commit or abort command to
finalize the local portion of the distributed transaction.
I did Google around and got some help to resolve this. Here are the steps I followed to fix this issue.
1) Connect to Oracle as sysdba by using this command
-- sqlplus sys as sysdba
2) select LOCAL_TRAN_ID
from dba_2pc_pending
This above select command will give
you list of all pending transaction ids and one id will match with the id
mentioned in the above error. you have to pick that id and delete it. Before attempting to delete (step 5) you need to first execute steps 3 and 4.
3) alter system enable distributed recovery;
Above statement enables distributed recovery
4) rollback force '5.4.426183';
commit;
Note - Use
ROLLBACK
statement with the FORCE
option and a text string that indicates either the local or global transaction ID of the in-doubt transaction to commit.
5) execute dbms_transaction.purge_lost_db_entry('5.4.426183');
Once the above procedure executes successfully then you may try your original Alter/DDL command and restart your app server.