Backend Development 6 min read

Generating Unique Order Numbers in Java: Risks, Testing, and Improved Approaches

The article examines a Java method that creates unique transaction order numbers by combining a timestamp with a four‑digit random code, discusses its collision risk, evaluates testing strategies—including stress testing and UUID replacement—and provides sample code for both generation and duplicate detection.

FunTester
FunTester
FunTester
Generating Unique Order Numbers in Java: Risks, Testing, and Improved Approaches

A colleague shared a Java utility for generating unique transaction order numbers and asked whether the approach has flaws and how to test it. The original code concatenates a timestamp formatted as yyyyMMddHHmmss with a four‑digit random number produced by getRandomLengthCode(4) :

/**
 * 生产唯一的交易订单号
 */
public static String createUniqueOrderNo() {
    SimpleDateFormat nyrsfm = new SimpleDateFormat("yyyyMMddHHmmss");
    return nyrsfm.format(new Date()) + getRandomLengthCode(4);
}

/**
 * 获取随机的短信验证码
 */
public static String getRandomLengthCode(int length) {
    return String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, length - 1)));
}

The method splits the order number into two parts: the current time down to seconds and a four‑digit random integer. The random part is generated by scaling a random double in the range [0,1) to [1,10) and then multiplying by 10^(length‑1), yielding a number between 1000 and 9999.

The main concern is the possibility of duplicate order numbers. Since the timestamp granularity is one second, only about 9,000 distinct random values are available per second. If more than 9,000 orders are created within a single second, collisions become inevitable.

Two testing proposals were discussed:

Explain the logic verbally (as above).

Attempt to generate duplicate order numbers through testing.

Proposal 1 was deemed ineffective because the business volume is low and the collision probability is considered negligible. Proposal 2 involved stress‑testing, but the test environment could only handle a few dozen QPS, making it difficult to reproduce collisions.

A partner suggested that in multi‑server environments the timestamp‑plus‑random approach could still clash. They recommended adding a user‑specific identifier or, more robustly, using a UUID. The revised code using UUID looks like this:

/**
 * 生产唯一的交易订单号
 */
public static String createUniqueOrderNo() {
    return UUID.randomUUID().toString();
}

To illustrate a simple duplicate‑detection test, the author provided the following Java snippet, which generates many random codes in a loop and records any repeats:

public static void main(String[] args) {
    List
list = new ArrayList<>();
    range(250).forEach(x -> {
        String randomLengthCode = getRandomLengthCode(4);
        if (list.contains(randomLengthCode))
            output(x);
        else
            list.add(randomLengthCode);
    });
}

The author invites readers to suggest better solutions, mentions future discussions on performance, and notes that adding a user‑specific tag or rate‑limiting order creation (e.g., one order per five seconds) are practical mitigations.

Disclaimer: the article is not to be reproduced by third parties (except Tencent Cloud). Additional technical articles and non‑technical reads are listed for further exploration.

javaTestingUUIDorder numberunique identifier
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.