SoFunction
Updated on 2025-04-13

Springboot3 implementation example of using redis to generate a unique order number

Generate an order number

There are many ways to generate a unique order number, including uuid, snowflake algorithm, etc. You can also use database constraints to generate a unique id, such as self-increase, but the performance of the database is relatively low. If you use the database to generate an order number, the efficiency is relatively low. We might consider using redis to generate a unique order number. Redis is natural single threaded and supports atomic operations of lua scripts. So these functions are very good.

Code implementation

import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;

@RestController
public class distr_lock {
    @Resource
    private RedisTemplate<String,String> redisTemplate;


    @GetMapping("/order")
    public void order() {
        for (int i = 0; i < 50; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 20; i++) {
                        String s = generateOrderId();
                        (s);
                    }
                }
            }).start();
        }
    }

    /**
      * We can adopt such a strategy,
      * Time is accurate to seconds + 7 digits of self-incremental number
      * This can achieve no more than 10 million orders placed by the same user in the same second
      * Then use time to create a key in redis, and then expire in 30 seconds
      */
    public String generateOrderId(){
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendValue(, 4) // Year, 4 digits                .appendValue(ChronoField.MONTH_OF_YEAR, 2) // Month, 2 digits                .appendValue(ChronoField.DAY_OF_MONTH, 2) // Date, 2 digits                .appendValue(ChronoField.HOUR_OF_DAY, 2) // Hours, 2 digits                .appendValue(ChronoField.MINUTE_OF_HOUR, 2) // Minutes, 2 digits                .appendValue(ChronoField.SECOND_OF_MINUTE, 2) // seconds, 2 digits                .toFormatter();

        // Get the string representation of the current time, without using - or: as a separator        String currentDateTime = ().format(formatter);
//        Long count = getAndExpireCounter(currentDateTime);
        Long count = getAndExpireCounterByLua(currentDateTime);
        String format = ("%07d", count);
        return currentDateTime + format;
    }



    public Long getAndExpireCounter(String key) {
        // Get Redis connection to execute transactions        Long increment = 0L;
        increment = ().increment(key);
        if (increment!=null && increment == 1) {
            // Set the expiration time, no transaction or lua script is used here            // Because I think the above autoincrement operation is atomic, that is, you will definitely get a value of 1            // If the redis service crashes and the expiration time is not set at this point, then we            // The service will also crash, and this key will always exist on the server, and this problem will occur, for the sake of rigor.            // It is best to use lua scripts to write, as the project will ensure more reliable results            (key, 30, );
        }
        // Get the value after increasing        return increment;
    }
	
	/**
      * The function of the entire script is:
      * 1. Check whether a key exists in Redis.
      * 2. If the key does not exist, set the value of the key to 1, and set the expiration time of 60 seconds for it, and then return 1.
      * 3. If the key already exists, increase its value by 1 and return the added new value.
      * Redis is atomic when executing Lua scripts, which means that during the execution of this script,
      * No other scripts or commands modify this key at the same time, thus ensuring the atomicity and consistency of the operation.
      * @param key
      * @return
      */
    public Long getAndExpireCounterByLua(String key) {
        // Define Lua scripts        String script =
                "if ('EXISTS', KEYS[1]) == 0 then " +
                        "   ('SET', KEYS[1], 1) " +
                        "   ('EXPIRE', KEYS[1], 30) " +
                        "   return 1 " +
                        "else " +
                        "   return ('INCR', KEYS[1]) " +
                        "end";

        // Use Redis's script to execute functions        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        (script);
        ();

        // Execute the script        return (redisScript, (key));
    }

This is the end of this article about the implementation example of Springboot3 using redis to generate a unique order number. For more related content related to Springboot3 redis to generate a unique order number, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!