0

I have this realy simple dao operation which works pretty fine(part of a JUnit test):

for (int i = 0 ; i < 5000 ; i++)
   mUserDao.saveUser(lUser, new Date().getTime());

the second parameter is a timestamp as long value. I test a kind of bulk save.

my question is: is it theoretical possible that I have two entries with the same long value in my database(mysql)? - in the same process.

A first look inside the relation shows me different long values for each entrie(At least the last millisecond is increased).

Thx in advance

Stefan

nano_nano
  • 12,351
  • 8
  • 55
  • 83

3 Answers3

1

Yes this is possible especially if you are having a fast hardware and that two saving operations are done in the same time. Then both created entries will have the same Long value.

Ali HAMDI
  • 365
  • 1
  • 11
  • stupid question but could I avoid this with: new Date().getTime()+1 ? – nano_nano Jan 07 '14 at 09:16
  • No this won't help. The best way is to use the class UUID that generates a new ID on each new creation . here is the documentation http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html – Ali HAMDI Jan 07 '14 at 10:57
1

You can't guarantee that new Date() will give you the current time accurately. Often it can be wrong by up to about 10ms. Calling new Date() uses System.currentTimeMillis(). The Javadoc for currentTimeMillis() says

Returns the current time in milliseconds. Note that while the unit of time of the return value is a millisecond, the granularity of the value depends on the underlying operating system and may be larger. For example, many operating systems measure time in units of tens of milliseconds.

So it's OS dependent. My experience is that Windows is particularly bad at giving you accurate dates.

And you certainly can't guarantee that you'll get different dates from successive calls to new Date().

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
  • is there a library to be os independent? – nano_nano Jan 07 '14 at 09:34
  • I'm not sure what you mean. The JVM has to rely on the OS to tell it the time; there's nowhere else it can get it from. So if the OS is giving out inaccurate times, there is no way that the JVM can work around that. – Dawood ibn Kareem Jan 07 '14 at 09:37
1

I think milliseconds since the UNIX epoch are still the best way to measure time in a reasonably accurate way. However, it's not really good to have a timestamp only as a primary key. As long as you have a unique primary key you don't really need unique timestamps.

In case for some reason you still want the timestamp to be unique, you can apply an 'artificial smear'. For example:

long last = 0;
for (int i = 0 ; i < 5000 ; i++) {
   long now = new Date().getTime();
   if (now <= last) {
      now = last + 1;
   }
   last = now;
   mUserDao.saveUser(lUser, now);
}

There are many ways this can be improved but the code above is just to illustrate the idea of a smear.

Sandman
  • 2,577
  • 2
  • 21
  • 32