如何根据当前日期生成UniqueId

问题描述 投票:4回答:6

我正在生成一个OrderId,它应该由yyMMddhhmmssMs组成,这个orderId代表Orders表的primarykey字段。

我生成订单ID的方式如下:

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTime {

    public static String getCurrentDateTimeMS() {
        Date dNow = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyMMddhhmmssMs");
        String datetime = ft.format(dNow);
        return datetime;
    }

    public static void main(String args[]) throws InterruptedException {
        for (int i = 0; i < 50; i++) {
            String orderid = DateTime.getCurrentDateTimeMS();
            System.out.println(orderid);
        }
    }
}

但是当我使用JMeter加载测试我的应用程序时,有100个用户,加速时间为2秒,其中大多数都抛出了Duplicate,如下所示

java.sql.BatchUpdateException: Duplicate entry '1410160239241024' for key 'PRIMARY'
        at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1269)
        at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:955)
        at com.services.OrdersInsertService.getData(OrdersInsertService.java:86)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)

如何根据当前时间生成UniqueId,以便无论存在多少并发用户,它都不会失败。

java
6个回答
6
投票

发生这种情况是因为for循环的速度比你的时间快:)。循环在小于毫秒的时间内迭代并生成值。你只能在想要向数据库插入单个值而不迭代时调用它对于价值观。

除此之外,您可以使用UUID用于此目的(对于字母数字值)。

for (int i = 0; i < 50; i++) {
        Date dNow = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyMMddhhmmssMs");
        String datetime = ft.format(dNow);
        System.out.println(datetime);
}

OUTPUT

141016030003103
141016030003103
141016030003103
141016030003103
141016030003103
141016030003103
141016030003103
141016030003103
141016030003103
//.....and more

4
投票

此代码将帮助您使用当前时间戳生成任意数量的唯一ID。生成的ID类型为long - 64位。当在与先前请求相同的毫秒时间内接收到生成新唯一ID的请求时,使用最低有效17位。它在下面的代码中标识为Sequence。这允许代码每毫秒生成65536个唯一ID。

/**
 * Unique id is composed of:
 * current time stamp - 47 bits (millisecond precision w/a custom epoch gives as 69 years)
 * sequence number - 17 bits - rolls over every 65536 with protection to avoid rollover in the same ms
 **/

public class UniqueIdGenerator {
    private static final long twepoch = 1288834974657L;
    private static final long sequenceBits = 17;
    private static final long sequenceMax = 65536;
    private static volatile long lastTimestamp = -1L;
    private static volatile long sequence = 0L;

    public static void main(String[] args) {
        Set<Long> uniqueIds = new HashSet<Long>();
        long now = System.currentTimeMillis();
        for(int i=0; i < 100000; i++)
        {
            uniqueIds.add(generateLongId());
        }
        System.out.println("Number of Unique IDs generated: " + uniqueIds.size() + " in " + (System.currentTimeMillis() - now) + " milliseconds");
    }

    private static synchronized Long generateLongId() {
        long timestamp = System.currentTimeMillis();
        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) % sequenceMax;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }
        lastTimestamp = timestamp;
        Long id = ((timestamp - twepoch) << sequenceBits) | sequence;
        return id;
    }

    private static long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }
}

2
投票

用这个:

int unique_id= (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE); 

0
投票

为每个订单ID添加唯一字符串,例如用户的电子邮件(如果它在数据库中是唯一的)或数据库中用户的ID。这使订单ID真正独一无二

String unique = timestamp + unique_user_field


0
投票

公共课测试{

public static void main(String[] args) {

    Date d=new Date();
    //it will return unique value based on time
    System.out.println(d.getTime());


}

}

你可以使用日期类的getTime方法。它返回自1970年1月1日00:00:00 GMT以来该日期所代表的毫秒数。


0
投票
I used a simple logical approach which combines current date and time.  That way it is absolutely unique in any given time.

public String  setUniqueID(){
    DateFormat dateFormat = new SimpleDateFormat("yyddmm");
    Date date = new Date();
    String dt=String.valueOf(dateFormat.format(date));
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat time = new SimpleDateFormat("HHmm");
    String tm= String.valueOf(time.format(new Date()));//time in 24 hour format
    String id= dt+tm;
    System.out.println(id);
    return id;   
}

This returns a unique id.
© www.soinside.com 2019 - 2024. All rights reserved.