如何根据当前日期生成UniqueId

时间:2014-10-16 09:25:05

标签: java

我正在生成一个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,以便无论有多少并发用户,它都不会失败。

9 个答案:

答案 0 :(得分:6)

这是因为for循环的速度比 time :)快。因为循环在小于毫秒的时间内迭代并生成值。你只能调用它当您想要将单个值插入数据库并且不迭代值时。

除此之外,您可以将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);
}

<强> 输出

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

答案 1 :(得分:3)

此代码将帮助您使用当前时间戳生成任意数量的唯一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 :(得分:2)

使用此:

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

答案 3 :(得分:0)

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

String unique = timestamp + unique_user_field

答案 4 :(得分: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以来由此日期表示的毫秒数。

答案 5 :(得分:0)

Sub RefreshAction()
Dim htm As Object
Dim Tr As Object
Dim Td As Object
Dim Tab1 As Object
Dim URL As String
Dim Colstart As Long
Dim HTML As Variant
Dim i As Long
Dim j As Long
Dim n As Long
Dim ss As Long


Application.ScreenUpdating = False
URL = "http://register.um.edu.my/kok_kosong_bi.asp"
Set HTML = CreateObject("htmlfile") 'Create HTMLFile Object
With CreateObject("msxml2.xmlhttp") 'Get the WebPage Content
    .Open "GET", URL, False
    .send
    HTML.Body.Innerhtml = .responseText
End With

Colstart = 1
j = 1
i = Colstart
n = 0

'Loop Through website tables
For Each Tab1 In HTML.getElementsByTagName("table")
    With HTML.getElementsByTagName("table")(n)
        For Each Tr In .Rows
            For Each Td In Tr.Cells
                Sheet1.Cells(j, i) = Td.innerText
                i = i + 1
            Next Td
            i = Colstart
            j = j + 1
        Next Tr
    End With
    n = n + 1
    i = Colstart
    j = j + 1
Next Tab1
Application.ScreenUpdating = True
Application.EnableEvents = True
Debug.Print Now() + TimeValue("00:00:05")
Application.OnTime Now() + TimeValue("00:00:05"), "RefreshAction", Schedule = True
End Sub

答案 6 :(得分:0)

您可以使用render() { return( <Table> <thead> <tr> { this.collection.arraylist.map((name) => { return this.getMoreNames(name) } } </tr> </thead> <Table> )} esLint is give me the error as described in my post subject. I read other post and added () but that did not work this.collection.arraylist.map((name) => ({ return this.getMoreNames(name) }) 来给字符串类似'u2mcggc1'

答案 7 :(得分:0)

我认为这将有助于生成包含20个字符的唯一时间戳。

public class DateTimeService {

    @Autowired
    private Clock clock;
    private LocalDateTime current;

    @PostConstruct
    public void init() {
        current = LocalDateTime.now(clock);
    }

    public synchronized LocalDateTime getUniqueTimestamp() {
        LocalDateTime now = LocalDateTime.now(clock);
        if (current.isEqual(now) || current.isAfter(now)) {
            current = current.plus(1, ChronoUnit.MICROS);
        } else {
            current = now;
        }
        return current;
    }
}

答案 8 :(得分:0)

在我看来,根据日期和时间获得唯一的字符串非常困难, 由于循环速度非常快,您很可能会得到重复的字符串。

但是这里我有一个带有 twist 的小代码,即使在循环中也可以每次都给出一个唯一的字符串。

public static synchronized String getUniqueStringEveryTime()
{
    
        Date dNow = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyyyMMddHHmmssSS");
        String datetime = ft.format(dNow);
        try
        {
            Thread.sleep(1);
        }catch(Exception e)
        {
            
        }
        return datetime;

}

上述简单的方法可以 100% 正确运行任意次数。