We want to batch upload IDOCs to our SAP, and use the EDI_DC40/SERIAL as the key to link the original data and the IDOC. But the max length of the EDI_DC40/SERIAL is 16, this process may be run on all the instances in the IS cluster at the same time, so the Timestamp string is not a good solution. And now we are using the sequence in Oracle DB, and this bring extra DB access to get the serial number every time. So we want to generate the serial number on IS like the UUID, but we don’t know how to limit the length in 16. So would you please share your experience on the serial number? Thanks in advance.
You can certainly do so using pub.math.random with fractionallength as 16 and then multiply it “10 raised to 16”.
Using random numbers isn’t a good approach. I’ve done something like this before, thinking that the likelihood of duplicate values was very small–and wouldn’t know that on the first day of production we encountered several duplicates generated by different machines.
Before delving into an alternative approach, are you sure that the DB call overhead is meaningful? The use of the DB, particularly in a multi-instance IS environment will guarantee no duplicates.
If you really want to do this IS, then a variation on the UUID is probably the way to go. There are a variety of UUID generation methods that are publicly available that you could start with and adapt for your needs.
If you don’t mind using non-public methods, there is a com.wm.util.text.UUID class in the client.jar that ships with IS. The generate() method returns a 32 character UUID (no dashes). You can potentially use the first 16 characters or some other subset. Create a Java service that calls this method. Run it a few times to see how you might be able to use parts of the string to create a 16 char string that will meet your needs.
Often the last or rightmost characters of a UUID are the ones that are unique, so examining the results of a few tests as Rob suggests is critical.
Also, please be aware that EDI_DC40/SERIAL has a special meaning inside SAP. It is a serialization field used to process IDOCs serially, rather than a unique identifier for the IDOCs. You will also not be able to use the UUID, mentioned by Rob, in this field as it has to be a number. In the past, We have used UUID in EDI_DC40/ARCKEY for the purpose you have mentioned.
If you must have a number, i personally prefer the DB call as it guarantees uniqueness. And if the numbers don’t need to be serial across multiple ISs, you can build a simple component in IS, that caches may be a 1000 sequence numbers in one DB call, and refills when empty. That way you can reduce the number of DB calls.
I’d offer that the optimization of caching a 1000 values at a time should be done ONLY after determining that calling the DB to get the next val for the sequence takes too much time.
a combination of SecureRandom nextInt() and System.identityHashCode on new Object() should suffice for your need of 16 digit non-db based number.
Thank you all. From your suggestions, I got the following approach: Get the current timestamp (System.currentTimeMillis()) and a random(java.lang.Math.random()*1000000), then convert them to the (0~9,a~z) dictionary base string, then concat them. And the max length of the concated string is 13. And concat 3 length server serial number. As I tested, I did not got duplicate numbers in one million. But it can not be sure unique in theory. From the UUID definition, the timestamp concat CPU clock should be unique, but how can I get the CUP clock? And any one has other approchs? Thanks a lot.