Calling a Subprogram form Batch & Online


We have a subprog that being called from batch & online.
The subprog task is to hold a recod (update mode) in order to generate a unique id for each record before perform ET.
If I called it, I will be on loop (err3145) until other will perform ET.
Last week 2 sessions called it (online & batch) in the same time.
Somehow we got a deadlock (for 30 Min.) until Adabas perform BT on the batch process & we did not get any error (the record was lost).
The 2 record got the same unique id, even it should not happend.
We do not know how it happend, the deadlock, the same record with uniqe id.
Can someone explain more?
Maybe there are more to think while calling form batch & online?

With Regards,

No, there is absolutely no difference whether the subprogram (or the
database access performed by it) is called from batch or online.

Two questions:

  • What Adabas and Natural versions ?
  • do you GET or FIND that record ?



one difference that is often configured between batch and online: batch usually has WH=ON, causing it to wait until the record is released and online usually has WH=OFF as we don’t want online users to wait for a held record, but be immediatedly given a 3145 to indicate that the record is held. GLOBALS command in each environment will show what the setting is.

How are you putting the record on hold? When you do a READ that has an UPDATE pointed to it, the record is not put on hold if a 3145 occurs.

you might post the unique id key generator subprogram and a description of how a calling program uses it.

If there is a reason (e.g. proprietary algorithm) that you cannot post the subprogram,
could you at least post how the subprogram “knows” what the last ID was?


I agree there is no difference between online and batch.

Normally a dead lock requires at least two records (not necessarily in same file) in play. A dead lock situation has to be timed out by the database TT parameter.

Another situation could be – which I would not call a dead lock - an online user holding a record across an input screen (and user has to press enter before it carries on) and another user (could be batch) that tries to get same the record with WH=ON. Then the second user will also wait (hang).

That you get the same unique id assigned twice must be because of a logic error in your application.


Yes, I put a record in Hold using a suprogram ‘x’ :

  if *error=3145
    rc := 2
    escape routine
rc := 1
read (1) file by sd
  if false
rc := 0

I read the newest record numreator & put it in hold, to prevent others to get the same numerator.
Others are put on hold for the record using external loop:

repeat until rc = 0
  callnat 'x' numerator rc


What is your Natural parameter ETEOP set to?


I looked at our Plog:

newrec ai - isn=x time=14:15:44 userid=y
delete bi isn=x time=14:42:39 userid=y

I dont have any delete command in our application.
I do not why I got “Delete” coommand, I think because of the Dead Lock, that I dont understand how it happend.


The ‘delete’ could be a result of you have been timed out and your transaction thus has been backed out.
Is isn=x the record with your unique-id? In this case it does not exist because it was deleted again.

Are you sure “Adabas” perform a Delete command when I get Time out??
I perform these command:

  1. store in file 1
  2. update file 2
  3. store file 2
  4. store file 1
  5. ET

The Record that wad deleled was store in step 1, and the update was not performed too,
because while trying to get a uniqe id for file 2 (step 3) the application got in a Deadlock because an online user,
that try too to get a uniqe id for file 2 (same subprogram as I mentioned before),
but I dont understand why I got a deadlock using the code I wrote.


Hi Hezi;

Two things to look at.

First, what happens in the program if RC=0? Is the record ever released?

Second. Are there any internal subroutines floating about in either the program or subprogram?

If so, you might have to ESCAPE MODULE rather than ESCAPE ROUTINE.


Hi Steve,

When I hold the last record, I do the steps I mentioned before (1-5).
No others internal subroutines.
I do not know escape module (maybe because nat version).
Does Adabas perform Delete command by itself (tt parameter)?


Yes, your complete transaction will be backed out to last commit point (last END TRANSACTION or BACKOUT TRANSACTION).

SYSAOS (session monitoring / display queues / display hold queue) and oper cmd DHQA can show you which records are in hold when the dead lock is running. Perhaps this can give you a clue.

Are you sure?
Will I see in the Plog file the command “DELETE” while getting backout because of timeout?
If I running in batch shouldnt I get an error because of that?
I didnot get error, the job ended ok.


This information you will not see on plog. You will not even see information about a BACKOUT TRANSACTION performed by a program. plog only contain store/update/delete information (among a lot of other internal information). In case of a store, it is just deleted again if the transaction is rolled back. plog contain only information needed to reestablish database. Commands performed are logged on clog.

“The job ended ok”- which job? You have mentioned both online and batch.

If there are two jobs in play, the other job may get the record when the dead lock is resolved by backing out the first one. Then the other job may succeed.

I meant the batch job I did not get nothing because of the backout.
Shouldnt I get an error?
The job just continued and ended ok.
If so, how can I cancel the job If getting bt because of tt parameter?
If I hold the record no matter from where (batch/online), how I got the same numerator for 2 records?
I thought using the code below I will solve it?



Well my friends I solve the Deadlock problem.
As it seems we got the classic one.
batch: online

  1. update on hold fnr=1 update on hold fnr=2
  2. store fnr=1 update on hold fnr=1 (failed 3145)
  3. update on hold fnr=2 (failed 3145)

Now, I need to check how come in my batch I did not get the error code (I think 3009)???


Check if you got any “on error” that could ignore the error,