error 3145

Hi,

I need to get last descripotr in a file so I wrote:
read (1) x by dscripotor.
to get it on hold I wrote:
if 0 = 1 then update end-if
when another program wants to get the last descripotr it’s get
error 3145, then we wrote retry, which is not ok because
the previous program store a new one.
my on error do escape routine.
I need to go bach my read(1) to get the new desciptor.
I hope you understood my question/

Thanks,
Hezi

Hi Hezi;

Sorry, but I really do not understand what you are trying to do; but will guess.

If you just want to know the last value of a descriptor field, say COUNTRY, you would do

HISTOGRAM (1) .... IN DESCENDING SEQUENCE COUNTRY
    write 'last country is' COUNTRY

Second guess; are you trying to create some sort of increasing key to assign to each new record? If you have non reusable ISNs you can use the ISN.

steve

… on the other hand, you can use a file with only one record. Set it in hold, do an update+end transaction, and do a retry in case of NAT3145.

Well,

I’ll try to explain my question:
I wrote:

Read (1) by descriptor
if 0 = 1 then update end-if

,to get the last new record stored, and to keep it in hold, and in
the end to add a new record.
while this, in parallel another session do same, but it gets error 3145
(because i hold the last new record)
We treat it with:

on error
if *error = 3145 then retry

which is not correct for this situation, because i’ll get not last new record,
but the one it is on hold.

It is very difficult (if not impossible) to recover once you’re in an ON ERROR block. I reserve ON ERROR for unanticipated and unrecoverable errors.

This is what you are seeing:

  • User Ralph reads ISN 101 from file APPLICATION and holds key value LATEST1.
    User Herzi reads file APPLICATION, but cannot hold ISN 101 because it is already held by Ralph, so he waits.
    Ralph generates key LATEST2, and stores ISN 202 in the APPLICATION file; an ET releases ISNs 101 and 202.
    Herzi is granted access to ISN 101 in hold status, and generates a new key, but finds that LATEST2 is already used.

Matthias’ post attempted to steer you in the right direction. The key generation process must be serialized to ensure that concurrent users generate new and/or unique keys. The way to do this is to create another file containing a control record in which the latest key value is stored. All users attempt to place that record on hold and update it with the last-generated value.

  • Ralph reads APP-CONTROL and holds ISN 303.
    Herzi reads APP-CONTROL and waits for ISN 303.
    Ralph generates a new key, stores a new record in APPLICATION, and updates APP-CONTROL ISN 303 with the new key value.
    Ralph issues an ET.
    Herzi is granted access to ISN 303 on hold, generates a new key, …

This scenario requires neither an ON ERROR nor a non-executable UPDATE.

ps For non-executable code, I use

IF  FALSE 
  THEN 
    ... some statements ... 
END-IF

Thanks,

But I am not sure I understood how come you do not need
On error and update.
How I keep the record in Hold?
How the second session waits (no retry)?

Hezi

Although the default setting is OFF, most shops set the Natural Parameter (NatParm) WH (wait for record on hold) to ON. This means that Natural and Adabas will retry automatically to place a record on hold for you. There is no need to code ON ERROR or RETRY explicitly.

You don’t need a bogus UPDATE, because you really will update the control record after you generate the new key value.

... application processing ...  
... populate APPLICATION view ...  
F.  
FIND CONTROL ...  
  ADD 1 TO CONTROL.key-field  
  UPDATE (F.)  
END-FIND  
ASSIGN APPLICATION.key-value = CONTROL.key-field  
STORE APPLICATION  
END TRANSACTION  
...

It is very important to minimize the code and elapsed time between the update of the control record and the ET, that is, minimize how long the control record is on hold, because another user likely is waiting for it.