我有一个简单的程序,但我不确定如何最好地实施停止死锁或记录锁的策略。我正在更新游标 LOOP 中的许多表,同时调用一个也更新表的过程。
死锁或记录锁存在问题,因此我的任务是解决程序遇到死锁或记录锁时崩溃的问题,但要休眠 5 分钟并继续处理任何新记录。
完美的解决方案是它跳过死锁或记录锁并继续处理其余未锁定的记录,休眠 5 分钟,然后在再次调用游标时拾取该记录。该程序继续运行一整天,直到它被杀死。
我的程序如下,我已经放入了我认为最好的内容,但是我应该在内循环而不是外循环内有异常吗?同时在内循环中有一个保存点?
PROCEDURE process_dist_data_fix
IS
lx_record_locked EXCEPTION;
lx_deadlock_detected EXCEPTION;
PRAGMA EXCEPTION_INIT(lx_record_locked, -54);
PRAGMA EXCEPTION_INIT(lx_deadlock_detected, -60);
CURSOR c_files
IS
SELECT surr_id
FROM batch_pre_dist_data_fix
WHERE status = 'REQ'
ORDER BY surr_id;
TYPE file_type IS TABLE OF batch_pre_dist_data_fix.surr_id%TYPE;
l_file_tab file_type;
BEGIN
LOOP
BEGIN
OPEN c_files;
FETCH c_files BULK COLLECT INTO l_file_tab;
CLOSE c_files;
IF l_file_tab.COUNT > 0
THEN
FOR i IN 1..l_file_tab.COUNT
LOOP
-- update main table with start date
UPDATE batch_pre_dist_data_fix
SET start_dtm = SYSDATE
WHERE surr_id = l_file_tab(i);
-- update tables
update_soundmouse_tables (l_file_tab(i));
END LOOP;
END IF;
Dbms_Lock.Sleep(5*60); -- sleep for 5 mins before looking for more records to process
-- if there is a deadlock or a locked record then log the error, rollback and wait 5 minutes, then loop again
EXCEPTION
WHEN lx_deadlock_detected OR lx_record_locked THEN
ROLLBACK;
Dbms_Lock.Sleep(5*60); -- sleep for 5 minutes before processing records again
END;
END LOOP;
END process_dist_data_fix;