Skip to content
Advertisement

Generate unique numbers with simultaneous access

Situation: People will order tickets on my system and i want to generate ticket numbers.

The application is not that big and it’s working already. Backend is completly written in vanilla php.

But i only tested with one user at a time. Now i guess there is a chance that several user will acess the the ticket order at the same time, since there is only a short time window to order within the company.

The database (MongoDB) holds every event as a document. Each document has a field that holds the first free ticket Number. After the payment process the php script checks how many tickets the user bought an will then start to generate the ticket numbers (get the current value -> increase -> save it to DB -> etc). Now when two people at the same time will do this somehting like this could happpen : both will get 2314 as the current available number and both will increase it afterwards. Now there are two tickets with the same ticket number.

I thought about changing to sql and get the id of the inserted row since this is already a unique number. I also thought about taking the current time + salt and hash it (but then there will be cruel ticket numbers).

But i want to know if there is a possibility to achieve this without using a db function like the one from sql. I guess this could be usefull on other scenarios as well, where i may cannot use something like the sql thing. I thought about somthing like “blocking the access to a number/function” until the first calling function will give it free again.

Advertisement

Answer

You could use hrtime()

<?php
// hrtime
echo hrtime(true).PHP_EOL.
    hrtime(true).PHP_EOL.
    hrtime(true).PHP_EOL.
    hrtime(true).PHP_EOL.
    hrtime(true).PHP_EOL;
    
// microtime
echo microtime(true).PHP_EOL.
    microtime(true).PHP_EOL.
    microtime(true).PHP_EOL.
    microtime(true).PHP_EOL.
    microtime(true).PHP_EOL.
    microtime(true);

Result:

25558478919927842
25558478919929611
25558478919930289
25558478919930576
25558478919930779
1597318697.2849
1597318697.2849
1597318697.2849
1597318697.2849
1597318697.2849
1597318697.2849

The above is comparable to several users will access the ticket order at the same time. As you can see microtime wont suffice.

But you could use the last 5 numbers from the above i.e 27842 and will most likely be unique.

Other than that you could place a user id in front for more entropy.

If you want consecutive and 100% protected from duplicates then your only option is to use an incremental id stored in a database.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement