3145 error

Our shop has a system that was written by people that didn’t understand some of the subtleties of adabas/natural. We have on error routines that do a retry on a 3145 error, and sometimes (based on my adabas review reports) they retry 50,000 times or more.

I’m trying to count the 3145 errors, and limit the retries to 200. But we don’t really want to kick the users out just because a record is on hold. I think the problem is in the programs that have read or find loops, reject lots of records, and have update logic. This puts all the records read on hold.

What I need is a way to find out who, or what program has the record on hold. Because we have a 3145 error we know the record is on hold, but by whom? Is there a way to find that out?

I’ve been a natural developer for 17 years, and I understand that you should use a get inside the read loop, and update the get. But, I can’t seem to convince the powers that be. If I could tell them what program has the record on hold I may be able to get through to them.

I got a similar problem on our Solaris-System and solved it.

I don’t know, whether the ADABAS-Utilities are the same on Mainframe and Open Systems or not. If so, please see the ADABAS-Documentation for “ADAOPR … di=hq”.

For more Information please see:

Hope this helps!

There is no “automatic” way I am aware of, but one option would be to use SYSRDC to track update commands (and their source) and match them to the Rsp145.

By the way: I guess 200 retries are done within a fraction of a second in most cases.
Wouldn’t it be better to give the user the possibility to choose between a RETRY and a Abort?

Or an alternative if the user does not want to be notified would be to use USR2027N to create a wait interval between retries.

This is one of those times where a Natural API for SYSAOS type functions would be invaluable!

Matthias, one of the ideas we kicked around was presenting a screen to the user asking if they’d like to try again. But I believe the only reason the record is on hold is because another program has it on hold for no reason.

Chad, that’s a great idea, to wait, perhaps a second, then retry.

Question: Is there any overhead associated with USR2027N?
Where are the user exits documented? I tried looking in all the natural manuals and haven’t found anything.

You should be able to find info on the Natural APIs using the SYSEXT utility.
Other than the callnat I don’t believe there is any significant extra overhead, I think it just causes the session to roll out (swap out?)… I don’t know the exact details, Wolfgang, help?

Just a strange thought. Based on your knowledge of the systems; would it be feasible for a day or so, to reduce the size of the record hold queue? Then wait to see who complains. This would “catch” the programs without GET-UPDATE logic.


It must not be a mass of held records to get a 3145. Maybe there is a control record to be updated by a single program. If many users run this program they will get this error.
On the other hand, if records are held while a map is shown, and the user goes for a coffee, other users are blocked from updates, too. Therefore this is very bad programming:

READ view
  INPUT map

should be replaced by

READ view
  INPUT map
  GT. GET view-u *ISN
  move fields of view to fields of view-u

to hold the record as short as possible.

Btw. Unconditional retry in online program is the worst a programm can do. At least a pause (USR2072N) or a pop up window to commit/abort the retry should be used. If a online program does unconditional retries, you could also start the natural session with WH=ON to achieve the same result for the users, but without the retry-overhead. I wouldn’t like to be your user :wink:

[quote="Wilfried B

Of course my example is not complete. But to make it as simple as possible I omitted some things:

  • Before the update you have to control some fields for value change. A good key field for this is a timestamp field that is changed with each update.
  • if the field has changed, the user must be informed that the record has changed
  • the program has to react on that change (backout transaction? Is the change relevant or not and so on).
    I stick to it: to hold the record during screen IO is not a good idea!

[quote="Wilfried B

Thanks for all the good input.

I have to agree with Wilfried, don’t keep a record on hold. I think that should be a shop standard. Before doing an update, you get the record and check the last-update-date field to see if it has been updated since it was first retrieved. You could get fancier with this if you wish. I just don’t think application programs should produce database errors. Just my humble opinion.

I’m going to do some testing with the USR2072N utility this weekend to see if it causes overhead. I’ll use natrje to submit 100 jobs that all execute USR2072N and see what effect it has on the CPU. With that utility you can’t define a wait period of less than a second, so I’m thinking that when a 3145 error is returned, we’ll do a retry once a second for maybe 5 seconds. That will be a huge improvement over what we do now, which is to do 50,000 retries in about 5 seconds.

And btw Wilfried, there is overhead with WH=ON, and I read in one of the SAG manuals that SAG does not recommend it. I’m not sure exactly what kind of overhead it is, if it stays in the command queue or what.

Steve, that’s an interesting idea, lowering the ISN hold queue. But, the same thing can be accomplished with an adabas review report. I’ve been writing review reports to show programs putting record after record on hold when there will be little or no actual updating.

Actually the worse thing we have is sub programs that read a large number of records, putting them on hold, then never doing an end transaction because it doesn’t find a record it wants to update. Our system was written by people that don’t know natural, and their code was not reviewed, and there have never been any programming standards. One standard they did adhere to was to have on error routines that have if 3145, retry, endif. And, when I got here, the transaction time out parameters were set at 14,400 (4 hours).

Sorry I took so long getting back, I have problems using the forum, and I’m told my account won’t get reactivated until Monday, so I just made a new one.

Please let us know your results. It would be very interesting…

If I remember correctly, a WH=ON submits an automatical RETRY every 10 seconds. So it is quite the same as RETRY + USR2072N

I agree! “IF *ERROR-NR = 3145 RETRY END-IF” is really bad in most cases. Of course there could be a reason for it. But then, it should be written into the code as a commentary.

BTW: Do you really need a maximal transaction time of 4 hours? It seems to be much too long for me…

Sorry I took so long to get back with this.

This weekend I wrote a little natrje job that submitted 30 different jobs that all executed the USR2027 utility with a 30 second delay. When the jobs first got submitted the cpu usage went way up, but during delay I didn’t see any cpu usage. Every job had .06 seconds of CPU usage, and that didn’t change with a different wait delay.

What I’m going to suggest is that on a 3145 error we execute USR2027 with a 1 second delay (1 second seems to be the minimum delay available), and do a retry every second for 5 seconds.

I’m not sure why the transaction timeout is set so high (4 hours), it was that way when I got here.