Ошибка ORA-02049: timeout: distributed transaction waiting for lock — решение
- Распределенная транзакция через DBLINK или интеграционный шлюз прерывается с ошибкой
ORA-02049: timeout: distributed transaction waiting for lock. - В alert.log появляются записи о сомнительных распределенных транзакциях (In-Doubt Distributed Transactions).
- Вью
DBA_2PC_PENDINGсодержит зависшие транзакции в статусе PREPARED или COLLECTING.
1. Поиск сессий, удерживающих распределенные блокировки
SELECT s.sid, s.serial#, s.username, s.osuser, s.program, l.type, l.lmode, l.request
FROM v$lock l
JOIN v$session s ON l.sid = s.sid
WHERE l.type IN ('TX', 'TM') AND l.block > 0;2. Проверка зависших транзакций 2-Phase Commit (2PC)
SELECT local_tran_id, global_tran_id, state, status
FROM dba_2pc_pending;3. Ручная принудительная фиксация или откат транзакции
Если транзакция зависла в распределенном протоколе двухфазной фиксации:
-- Принудительный откат
ROLLBACK FORCE 'LOCAL_TRAN_ID_HERE';
-- Или принудительный коммит
COMMIT FORCE 'LOCAL_TRAN_ID_HERE';4. Увеличение таймаута ожидания распределенных блокировок
ALTER SYSTEM SET distributed_lock_timeout = 120 SCOPE=BOTH; Частые вопросы (FAQ)
Что означает параметр DISTRIBUTED_LOCK_TIMEOUT?
Он задает время в секундах (по умолчанию 60 сек), в течение которого распределенная транзакция ждет освобождения ресурса, заблокированного другой сессией, перед выбросом ORA-02049.
Почему возникают In-Doubt транзакции?
Они возникают при внезапном разрыве сети или падении одного из узлов СУБД в фазе между PREPARE и COMMIT двухфазного протокола фиксации.
Как очистить запись из DBA_2PC_PENDING после принудительного отката?
Выполните процедуру: EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');
Может ли фоновый процесс RECO автоматически устранить ORA-02049?
Процесс RECO (Recoverer) автоматически опрашивает удаленные узлы и разрешает состояние in-doubt транзакций, как только сетевая связность восстанавливается.