View previous topic :: View next topic
|
Author |
Message |
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
Hi All,
I have a situation, where I should create a unique id (length=25) in my COBOL program (CICS batch). Below given the format.
Code: |
Position --> 0123456789012345678901234
Data --> 2014012310584220*********
Meaning --> YYYYMMDDHHMMSSMSRANDOMNUM |
I've tried the below code for generate unique id.
Code: |
01 WS-CURRENT-DATE-FIELDS.
05 WS-CURRENT-DATE.
10 WS-CURRENT-YEAR PIC 9(4).
10 WS-CURRENT-MONTH PIC 9(2).
10 WS-CURRENT-DAY PIC 9(2).
05 WS-CURRENT-TIME.
10 WS-CURRENT-HOUR PIC 9(2).
10 WS-CURRENT-MINUTE PIC 9(2).
10 WS-CURRENT-SECOND PIC 9(2).
10 WS-CURRENT-MS PIC 9(2).
05 RAND-NO1 PIC 9(9).
05 WS-SEED PIC S9(4) COMP.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-FIELDS.
MOVE WS-CURRENT-MS TO WS-SEED.
COMPUTE RAND-NO1 = FUNCTION RANDOM(WS-SEED) * 999999999.
MOVE WS-CURRENT-DATE-FIELDS TO WS-UNIQUE-ID(1:16).
MOVE RAND-NO1 TO WS-UNIQUE-ID(17:9). |
It is generating below output as expected:
Code: |
2014012311062688400936804 |
But this program runs so much time from different users, where there is a posibilities of running multiple times at the same TIMESTAMP.
So the RANDOM function returning the same value and it because non-unique.
Could you guys can help me to overcome this issue. Even if you have any other logic/way to generate a unique id will also work for me.
Appriciate you efforts. |
|
Back to top |
|
|
Terry Heinze
JCL Moderator
Joined: 14 Jul 2008 Posts: 1249 Location: Richfield, MN, USA
|
|
|
|
WS-CURRENT-MS is only "hundredths" of a second of the current time. Can you replace it with a variation of MSSECONDMINUTEHOUR by using FUNCTION REVERSE of current time and expanding your seed length to S9(9) comp-5? |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
Hi Terry,
I could try that, but, When the seed is same, output from RANDOM function is also same.
So, if this program runs twice in the same TIMESTAMP, RANDOM function returns the same random number, which I don't want.
Anyway I'll try your solution. |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
You need to find something unique to include with your seed value -- in CICS systems, task number is usually a good choice. |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
I agree Robert, Could you also give a hint about getting TASK number in a program? |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
I found that EIBTASKN will have the task number.
I couldn't test this scenario as we can't test in development for the same TIMESTAMP. I'll test in UAT and get back to you.
Could anyone brief, how this EIBTASKN getting generated, just curious ? |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
You need to understand the use of the seed.
The "random" number is a pseudo-random number generated by formula. Once one value is returned, the next value will always be the same. You don't have to worry about that in any way, it does not matter, but should be documented.
The "seed" tells random where to start. The same value seed always returns the same "random" value. The point of the seed is to give a reproduceable result.
Typically, you only provide one seed per run-unit. Show/record the seed. The rest happens automatically within the function processing.
If you only specify the seed once, you will not get a duplicate. If you don't specify the seed at all, you won't get a duplicate, but you will not be able to reproduce the sequence. |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
I'm completely understand Bill, and same found in here.
Quote: |
For a given seed value, the sequence of pseudorandom numbers will always be the same. |
When the program running multiple times with the same seed or without seed, all the output from RANDOM will be same.
So I need some unique seed to be used in RANDOM, which was well suggested Robert. Appreciate for your efforts though. |
|
Back to top |
|
|
enrico-sorichetti
Superior Member
Joined: 14 Mar 2007 Posts: 10873 Location: italy
|
|
|
|
Quote: |
So I need some unique seed to be used in RANDOM, which was well suggested Robert. Appreciate for your efforts though. |
did You care to try to understand what You were told ???
the seed is used ONLY during the TESTING phase in order to obtain reproducible results
once the testing is done DO NOT USE THE SEED and the random will return different values at each run of the program
thats the only case where audit/quality control will approve a promote to production of a source that has not been tested AS-PROMOTED |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
Of Course Enrico, I did understand, but if you run a program without seed, it will produce same set of random numbers.
I strongly suggest you to try this on your own (I've tried before posting here).
Quote: |
the seed is used ONLY during the TESTING phase in order to obtain reproducible results |
I guess, when seed is not specified it set to 'zero' as per this link
and Seed is not only for testing purpose, when we need of new sequence of pseudo-random numbers, we should use 'SEED'. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
sureshpathi10,
In the code you have shown, you are using a seed every time. If you do this, you no longer have a random distribution.Understand the difference between a random distribution and something which looks sufficiently different from the last one that you think you have "random numbers".
The distribution may not matter in your case.
You limit your seed to four digits (or about 1/3 of five digits, depending on compile option).
This means, whatever your source of the seed, you have a maximum of 10,000 sequences. If using multiple seeds in a day, you will quickly run out of uniqueness for the nine-digit portion of your data, even though it is nine digits.
Use one seed per day. Make the seed value pretty big (very big) and not just big with a whole sequence of leading/trailer zeros (read the manual, the Enterprise COBOL, not ILE COBOL one). I always recorded the seed value, but can't say I used random numbers often and like enrico, I suspect, only from the Assembler RANDOM macro.
What is the multiply by lots of nines for? OK, I know what it is for, but why do it like that? Have a search here, there is a previous discussion you may find useful. |
|
Back to top |
|
|
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
Quote: |
Could anyone brief, how this EIBTASKN getting generated, just curious |
The CICS Task Number (EIBTASKN) is generated internally by CICS (assigned to each Task) for each region and can be found in the TCA, mapped to DSECT DFHTCA, for each TCB. Don't try addressing the TCA in TS/3.2 and greater because the TCA-address (located in the CSA) is Fetch Protected (due to Threadsafe) and there's a different method to obtain the TCA-address. Just stick with EIBTASKN and you'll be fine.
As far as the random-number issue, you may consider using EIBTASKN (4-Bytes Packed-Decimal), the region's APPLID (8-Bytes Display) and a current Store-Clock value (either the standard 8-Byte binary-doubleword (STCK) or the extended 16-Byte binary-quadword (STCKE)).
Sub-Program "GETSTCK" -
Code: |
*PROCESS RENT PROGRAM IS RE-ENTRANT
***********************************************************************
*---------------------------------------------------------------------*
* *
* THIS SUB-PROGRAM RETURNS THE CURRENT STORE-CLOCK VALUE TO *
* THE CALLER AND CAN BE USED IN BOTH CICS AND BATCH. THE PPT *
* EXECUTION-KEY CAN BE 'USER' OR THIS SUB-PROGRAN CAN BE *
* STATICALLY CALLED (NO PPT-ENTRY REQUIRED). *
* *
* CALL SYNTAX: *
* *
* 03 WS-GETSTCK-PARM-REC. *
* 05 WS-GETSTCK-TOD PIC S9(18) BINARY. *
* 05 WS-GETSTCK-TOD-X REDEFINES WS-GETSTCK-TOD *
* PIC X(08). *
* 05 WS-GETSTCK-PACKED PIC X(16). *
* 05 WS-GETSTCK-RSA PIC X(72). *
* 03 WS-GETSTCK PIC X(08) VALUE 'GETSTCK'. *
* *
* CALL WS-GETSTCK USING WS-GETSTCK-PARM-REC. *
* *
* NOTE: WS-GETSTCK-PARM-REC DOES NOT REQUIRE INITIALISATION. *
* *
*---------------------------------------------------------------------*
***********************************************************************
PRINT GEN ACTIVATE MACRO EXPANSION
PRMDSECT DSECT PRMDSECT (R7)
USING *,R7 INFORM ASSEMBLER
PRMBEGIN EQU * BEGIN-PARMAREA
PRMSTCK DS D CURRENT STORE-CLOCK (BINARY)
PRMSTCKP DS PL16 CURRENT STORE-CLOCK (PACKED)
PRMRSA DS XL72 REGISTER-SAVEAREA
PRMLGTH EQU *-PRMBEGIN PARMAREA-LGTH
GETSTCK CSECT BEGIN CSECT (R3)
USING *,R3 INFORM ASSEMBLER
SAVE (14,12) SAVE REGISTERS
LA R3,0(,R15) CSECT ADDRESSABIITY
J ADDRPLST ADDRESS PARMLIST
EYECTCHR DC CL47' <<< ASSEMBLY DATE/TIME: &SYSDATC/&SYSTIME..00 >>>'
ORG EYECTCHR+6 REDEFINITION
DC X'A2A285948293A8' LOWER-CASE 'SSEMBLY'
ORG EYECTCHR+15 REDEFINITION
DC X'81A385' LOWER-CASE 'ATE'
ORG EYECTCHR+20 REDEFINITION
DC X'899485' LOWER-CASE 'IME'
ORG EYECTCHR+L'EYECTCHR RESET LOCATION-COUNTER
ADDRPLST DS 0H ENSURE ALIGNMENT
L R7,0(,R1) PRMDSECT ADDRESSABILITY
XC PRMBEGIN(PRMLGTH),PRMBEGIN
LA R15,PRMRSA POINT TO OUR SAVEAREA
ST R13,4(,R15) BACKWARD-CHAIN
ST R15,8(,R13) FORWARD-CHAIN
LR R13,R15 POINT TO OUR SAVEAREA
STCK PRMSTCK GET CURRENT-STCK
LG R1,PRMSTCK PREPARE FOR 'LPGR'
LPGR R1,R1 MAKE IT POSITIVE
CVDG R1,PRMSTCKP MAKE IT A PL16
XR R15,R15 SET 'ALL IS WELL' RC
OC PRMSTCK,PRMSTCK STORE-CLOCK IS NON-ZERO?
JNZ RTN2CLLR YES, RETURN TO CALLER
XC PRMSTCKP,PRMSTCKP ENSURE X'00'S
LA R15,16 SET 'INVALID' RC
RTN2CLLR EQU *
OI PRMSTCKP+L'PRMSTCKP-1,X'0F'
L R13,4(,R13) RESTORE CALLER'S R13
XC PRMRSA,PRMRSA CLEAR OUR 'RSA'
RETURN (14,12),RC=(15) RESTORE REGISTERS AND RETURN
LTORG ,
YREGS , MVS REGISTER-EQUATE
GETSTCK AMODE 31 ,
GETSTCK RMODE ANY ,
END , END 'GETSTCK'
|
It was necessary to convert the STCK value to a PL16 within "GETSTCK". So, when you return to the caller, WS-GETSTCK-PACKED is treated as a PIC X(16) and can be moved as-is.
But after viewing a WS-GETSTCK-PACKED returned value, you could safely use positions 6-16 as part of your Random number (effectively, a PL11, which in COBOL is 9(21) PACKED-DECIMAL (if ARITH(EXTEND) were active).
This eliminates having to compile the calling program, specifying the ARITH(EXTEND) compiler option, which your compiler may or may not support.
IIRC, ARITH(EXTEND) was introduced with COBOL for OS/390, version 2.2.1 (about 11-13 years ago), but I've slept since then.
HTH.... |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello,
Is it possible that there is no need for a random number? Unless i misunderstand, what is needed is a unique number. Why does it need to be random? |
|
Back to top |
|
|
enrico-sorichetti
Superior Member
Joined: 14 Mar 2007 Posts: 10873 Location: italy
|
|
|
|
I was applying <some other language> rules ( REXX in this case )
probably worth looking at the equivalent LE function CEERAN0
-CEERAN0--(--seed--,--random_no--,--fc--)--------------------><
seed (input/output)
A fullword binary signed integer representing an initial value used to generate random numbers.
seed must be a variable; it cannot be an input-only parameter. The valid range is 0 to +2,147,483,646.
If seed equals 0, the seed is generated from the current Greenwich Mean Time.
On return to the calling routine, CEERAN0 changes the value of seed so that it can be used as the new seed in the next call.
random_no(output)
An 8-byte double precision floating-point number with a value between 0 and 1, exclusive.
If seed is invalid, random_no is set to -1 and CEERAN0 terminates with a non-CEE000 symbolic feedback code.
fc (output)
A 12-byte feedback code, optional in some languages, that indicates the resu |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
Thanks Bill O'Boyle. I really appriciate your concerns.
I think, I owe Bill and Enrico a deep explanation of my situation.
(I've fixed it as Robert suggested and it is working fine).
I've a program with only one calling to RANDOM function.
Code: |
COMPUTE RAND-NO1 = FUNCTION RANDOM * 999999999. |
When I run this program without any seed I get "442707155".(run-unit 1)
When I run again I get the same value again.(run-unit 2) and so on.
I included a seed (millisecond) to the random function. So, when I test this program, it had given different random numbers as seed value were kept on changing.
At one case, where the seed value is same (consider this program running twice (run-unit1 & run-unit2) at the same millisecond) it produces the same random number, which affected my logic. So, I had come up with some seed values which will be unique for run-unit.
I hope, I didn't confuse more
Thanks guys for all your efforts.
|
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello,
I'm still confused why a random number is needed?
For many years getting the "next available number" has worked well. |
|
Back to top |
|
|
Terry Heinze
JCL Moderator
Joined: 14 Jul 2008 Posts: 1249 Location: Richfield, MN, USA
|
|
|
|
As Dick has mentioned, "next available number" guarantees uniqueness. |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
could you tell me what is next available number ? |
|
Back to top |
|
|
Nic Clouston
Global Moderator
Joined: 10 May 2007 Posts: 2455 Location: Hampshire, UK
|
|
|
|
Quote: |
could you tell me what is next available number ? |
One more than the last number assigned - you have to keep track of it. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello,
There are various ways to do this . . .
Typically the "next available" number is kept in a file or db table and as each new number is "taken" the number is incremented. |
|
Back to top |
|
|
sureshpathi10
Active User
Joined: 03 May 2010 Posts: 154 Location: Kuala Lumpur
|
|
|
|
This program is running million times a day and possibilities of running multiple times in a same TIME-STAMP.
So, I don't want to create a file/db-table to fetch the value and worry about these things.
1. Waste of resource (file/db)
2. Waste of process (read & update file/db)
3. Waste of CBU time (since I/O operation)
4. Cause of Deadlock.
A simple RANDOM function with unique seed would do my needful. It would be much faster then getting "next available number".
I'm sure "next available number" method will work on normal program that runs minimum times. Appreciate your suggestions |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19244 Location: Inside the Matrix
|
|
|
|
Hello,
A million executions is not so many . . .
Also, i'll wager that using a file/table will add almost invisible overhead compared to whatever this process does.
Why do you believe the random number would be free?
If the next available number is in a file/table, it may never leave memory and there would be only logical i/o, not physical i/o.
There should be no chance for a deadlock if the code is properly implemented. If the code was written to get the next available as the first part of the code (and commit the change), the chance of a time-out is Greatly reduced if not eliminated.
Sounds like you already decided you want to use random. Keep in mind that this Can cause a duplicate that has to be dealt with. |
|
Back to top |
|
|
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
In the CICS Forum, review the Sticky program DATETIME
ibmmainframes.com/viewtopic.php?t=61935
It's for CICS only (can be modified to be for Batch as well).
The Timestamp granularity is down to the microsecond.
If you combine the Date/Time (date-packed is PL5'0CCYYMMDD' and the time-packed is PL13'0HHMMSSTHMIJU"), together with the Task-Number as a PL4, you have a unique random number. |
|
Back to top |
|
|
|