Joined: 31 Aug 2007 Posts: 5 Location: Milwaukee WI
I checked the archives and apparently no one has had a similar problem to what I'm having.
We have a CICS transaction that can create up to 20 pairs of transactions that get passed to a sub-program that writes them to a VSAM file. The key is time followed by tran type. The transaction pairs are coded 600 and 620.
Up until now, we've been relying on the timestamp to keep the pair together. Lately we've been getting two pairs with the same timestamp. This causes the two 600 transactions to be sorted together and the two 620's sorted together.
We are using:
EXEC CICS ASKTIME
MOVE EIBTIME TO PCOM-D-TRAN-TIME.
According to the manual the ASKTIME function updates the EIBTIME and I'm confident that it is otherwise we would be getting tons of dups.
Here are how the key fields are defined:
WS-CICS-ABSTIME is PIC S9(16) COMP.
PCOM-D-TRAN-TIME is PIC S9(7).
It would appear that when the sub-program gets the 40 transactions (20 pairs) it is running so fast that occasionally it will write two pairs with the same timestamp. Apparently the S9(7) does not hold a small enough time imcrement for each one to be unique.
I cannot change the record layout to increase the size of the PCOM-D-TRAN-TIME field. My thought was to use the low order 7 bytes of the WS-CICS-ABSTIME field for the timestamp in the transactions instead of EIBTIME.
In your opinion, would this be unique enough to solve our duplicate problem?
Can you suggest a method that would guarantee us a unique time for each transaction pair?
Joined: 06 Jun 2008 Posts: 8217 Location: Dubuque, Iowa, USA
Look at the manual again -- EIBTIME is 0HHMMSS+, so if you get more than one a second you'll get duplicates. Using the last 7 digits of ASKTIME ABSTIME will remove this problem as that has the time to the nearest 1/100th of a second. You could still get dups if you're pumping a LOT of data through the transactions but it's much less likely.
For CICS environments, it is recommended that the PPT entry for this sub-program be CICSKEY (Parm=EXECKEY) and it should be accessed from a HLL via a LINK-API, passing a 16-Byte commarea.
Also, the 16-Byte parm required for the Macro should be obtained via a CICS GETMAIN (CICSDATAKEY) and not the default of USERDATAKEY.
Cross-Memory services (LINKAGE=SYSTEM) will most likely go belly up (S0C4) if Storage Protection is "ON" in the SIT and the above 16-Byte parm being used is obtained from USERDATAKEY.
After completing the Cross Memory service, the 16-Byte parm will contain X'HHMMSSTHMIJU' in the first 8-Bytes and the date (whatever format you've chosen) in the last 8-Bytes. Note that both of these values are packed-decimal without a sign.
Do NOT use LINKAGE=SVC (or let it default to this), as this will expand to an SVC 11, a big no-no in CICS.
Even though the PPT Execution Key may specify CICSKEY, DFHEISTG is always allocated in USER Key.
As part of the cleanup process, move the 16-Byte components to the commarea, issue a FREEMAIN, load R15 with a return-code (hopefully, it's F'0') and use the DFHEIRET Macro to return to the Linker with the R15 value.
Then (assuming this is a COBOL Linker) the RETURN-CODE SPECIAL-REGISTER can be checked for success or failure.
Joined: 14 Jul 2008 Posts: 1249 Location: Richfield, MN, USA
I had a similar situation several years ago. I needed to assign the same DB2 timestamp to all of the detail rows associated with a header row. I used the CCYY-MM-DD-HH.MM.SS portion of DB2s time stamp and generated my own value of microseconds for the details. When the HH.MM.SS value changed, I'd reset the microseconds to 000000. You could use a method similar to that to generate your own value of time insuring the same value of time for your 600 and 620 records.