Thursday, October 8, 2026

Oracle TX Row Deadlock (ORA-00060) Catch-Retry Endless Loop Test

In this Blog, we will show a Plsql program with TX Row Deadlock Catch-Retry, which will run in endless loop
if not restricted with deadlock counter.

Note: Tested in Oracle 19c


1. Test Setup


First we create a table with 2 rows, and a Plsql code to update them.

drop table test_dl_tab;

create table test_dl_tab as select level id, 0 cnt from dual connect by level <=2; 

select * from  test_dl_tab;

create or replace procedure test_dl_proc(p_id_1 number, p_id_2 number, p_dl_limit number := 100, p_sleep_init number := 10, p_sleep_dl number := 2) as
  e_deadlock_detected exception;
  pragma exception_init(e_deadlock_detected, -60);
  l_start      number := dbms_utility.get_time;
  l_end        number := dbms_utility.get_time;
  l_time_limit number := (p_dl_limit * (3 + p_sleep_dl) + 30);
  l_dl_cnt     number := 0;
begin
  update test_dl_tab set cnt = cnt + 1 where id = p_id_1;
  dbms_session.sleep(p_sleep_init);
  l_start := dbms_utility.get_time;
  l_end   := dbms_utility.get_time;
  while l_dl_cnt < p_dl_limit and (l_end - l_start)/100 < l_time_limit loop
    begin
      update test_dl_tab set cnt = cnt + 1 where id = p_id_2;
      dbms_session.sleep(p_sleep_dl);
    exception when e_deadlock_detected then
      l_dl_cnt := l_dl_cnt + 1;
      dbms_session.sleep(p_sleep_dl);
    end;
    l_end   := dbms_utility.get_time;
  end loop;
  
  -- commit needed
  -- Deadlock is a statement level rollback, locked source still locked. Other session is in TX Wait
  -- Otherwise "log buffer space" in TX waiting session
  commit;   
  dbms_output.put_line('Deadlock Hits = '||l_dl_cnt||' Within (seconds) = '||((l_end - l_start)/100));
end;
/


2. Test Run


Open two Sqlplus windows (SESSION-1 and SESSION-2), in SESSION-1, we update Row 1, then Row 2 with deadlock counter limited by 20. Whereas in SESSION-2, they are updated in reverse order.

-- Start in SESSION-1 
exec test_dl_proc(1, 2, 20);

-- Start in SESSION-2 within 10 seconds of SESSION-1 start
exec test_dl_proc(2, 1, 20);


3. Test Outcome


Here the output from both sessions.

-- SESSION-1 
SQL > exec test_dl_proc(1, 2, 20);
  Deadlock Hits = 20 Within (seconds) = 103.68

-- SESSION-2
SQL > exec test_dl_proc(2, 1, 20);
  Deadlock Hits = 19 Within (seconds) = 131.78
If they are not limited, the test will run in an endless loop.