Deadlock

Posted by Nithila Pillai on 03-Apr-2017 16:25

Two different procedures are deadlocking each other by accessing the same record from two different sessions.  Not sure if any other workaround to deal this type of scenario. 

Could someone pls suggest on this? - Thanks.
For example, 
Proc-1.p
Do Transaction:
  Access the record with exclusive-lock no-wait.
  If locked then
  Repeat while locked <rec>:
      Access the record with exclusive-lock no-wait.
  End.
  if avail <rec> then
    update <rec>.
End transaction.
Proc-2.p
Do  Transaction:
  Access the record with exclusive-lock no-wait.
  If locked then
  Repeat while locked <rec>:
      Access the record with exclusive-lock no-wait.
  End.
  if avail <rec> then
    update <rec>.
End transaction.

Posted by Thomas Mercer-Hursh on 03-Apr-2017 16:52

If a third session locked the record before these sessions were started and held that lock indefinitely, then these sessions would spin their wheels waiting for the lock to get free.  But, David is right, for a deadly embrace you need two records.

Posted by David Abdala on 03-Apr-2017 16:36

I may be wrong, but that doesn't sounds enough for a deadlock.

You need at least two records lock to get a deadlock: Proc1 has a lock on Rec1, Proc2 has a lock on Rec2, then Proc1 tries to get a lock on Rec2 and Proc2 on Rec1 == 'deadlock'.

Your example is not enough for a deadlock, one of the procs will get the lock and exit, and then the other will do.

To avoid multirecord deadlocks, you need to get all the locks before doing the job and, if any lock fails, release all the records, and retry (or fail). That means having as many buffers as required:

def buffer b1 for table.

def buffer b2 for table.

find b1 exclusive-lock.

find b2 exclusive-lock.

if not available b1 or no available b2 then release and exit.

do the job.

release and exit.

All Replies

Posted by David Abdala on 03-Apr-2017 16:36

I may be wrong, but that doesn't sounds enough for a deadlock.

You need at least two records lock to get a deadlock: Proc1 has a lock on Rec1, Proc2 has a lock on Rec2, then Proc1 tries to get a lock on Rec2 and Proc2 on Rec1 == 'deadlock'.

Your example is not enough for a deadlock, one of the procs will get the lock and exit, and then the other will do.

To avoid multirecord deadlocks, you need to get all the locks before doing the job and, if any lock fails, release all the records, and retry (or fail). That means having as many buffers as required:

def buffer b1 for table.

def buffer b2 for table.

find b1 exclusive-lock.

find b2 exclusive-lock.

if not available b1 or no available b2 then release and exit.

do the job.

release and exit.

Posted by Thomas Mercer-Hursh on 03-Apr-2017 16:52

If a third session locked the record before these sessions were started and held that lock indefinitely, then these sessions would spin their wheels waiting for the lock to get free.  But, David is right, for a deadly embrace you need two records.

This thread is closed