首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle ORA-01591 錯誤完整解決方案:分散式交易鎖定處理實務

     編輯:Oracle 資料庫基礎

錯誤背景

ORA-01591 錯誤訊息為「lock held by in-doubt distributed transaction」,通常發生於分散式交易(Database Link 交易)因網路中斷、遠端資料庫異常等原因,導致交易處於「in-doubt」狀態,阻塞後續操作。

解決步驟

步驟 1:找出未完成的本地交易 ID

SELECT 'ROLLBACK FORCE ''' || LOCAL_TRAN_ID || '''' FROM SYS.PENDING_TRANS$;

步驟 2:嘗試提交或回滾強制解決

ROLLBACK FORCE 'LOCAL_TRAN_ID';
COMMIT FORCE 'LOCAL_TRAN_ID';

步驟 3:若上述失敗,從資料字典強制清除交易記錄

SET TRANSACTION USE ROLLBACK SEGMENT SYSTEM;
DELETE FROM DBA_2PC_PENDING WHERE LOCAL_TRAN_ID = 'LOCAL_TRAN_ID';
DELETE FROM PENDING_SESSIONS$ WHERE LOCAL_TRAN_ID = 'LOCAL_TRAN_ID';
DELETE FROM PENDING_SUB_SESSIONS$ WHERE LOCAL_TRAN_ID = 'LOCAL_TRAN_ID';
COMMIT;

步驟 4:批次處理多筆收集狀態交易(PL/SQL 產生動態 SQL)

BEGIN
  FOR r IN (SELECT LOCAL_TRAN_ID
            FROM DBA_2PC_PENDING t
            WHERE t.STATE = 'collecting') LOOP
    DBMS_OUTPUT.PUT_LINE('DELETE FROM DBA_2PC_PENDING WHERE LOCAL_TRAN_ID = ''' || r.LOCAL_TRAN_ID || ''';');
    DBMS_OUTPUT.PUT_LINE('DELETE FROM PENDING_SESSIONS$ WHERE LOCAL_TRAN_ID = ''' || r.LOCAL_TRAN_ID || ''';');
    DBMS_OUTPUT.PUT_LINE('DELETE FROM PENDING_SUB_SESSIONS$ WHERE LOCAL_TRAN_ID = ''' || r.LOCAL_TRAN_ID || ''';');
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('COMMIT;');
END;
/

執行上述產出的 DELETE/COMMIT 指令即可批次清理。

步驟 5:終極手段——重啟資料庫實例

若所有指令均失效,可嘗試重啟 Oracle 服務。實務經驗顯示,在執行 COMMIT FORCE 失敗後重啟,鎖定有機會自動釋放(前提是已嘗試過強制提交)。

預防建議

  • 監控 DBA_2PC_PENDING 視圖,設定告警偵測長時間 in-doubt 交易
  • 優化網路穩定性,減少 Database Link 斷線機率
  • 應用端妥善處理異常與重試邏輯,避免交易懸而未決

總結

ORA-01591 處理核心在於:識別交易 ID → 強制提交/回滾 → 字典層級清除 → 實例重啟。建議依序嘗試,並做好事前監控與事後複盤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved