For our customers, I need to generate unique barcodes. No customer shall have two identical barcodes. The barcodes are built up as follows:
I want to keep track per customer which was the latest index number used, and when generating a barcode, retrieve the latest index number and increment that index number by one.
The problem now occurs when two processes try to generate barcodes at the same time. Process A and B both ask the latest index number, both receive the same latest index number and both create the same barcode code.
Is there a way to ensure that even when offering the barcode generation asynchronously, no duplicate barcodes are generated? The system to build it in is Django 1.9, Python 3.5 with a PostgreSQL database.
That's one of the tools backed into database engines, so how about using it for that purpose? It is a sequence. It is the very same tool that is used for generating primary key values (which I assume are not an option for some reason in your case, otherwise just use it).
Unfortunately, it is not handled by Django ORM, but you may create one directly like this:
CREATE SEQUENCE barcodes START WITH 100;
You may then use it in anytime by performing a direct SQL query from your django application:
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("select nextval('barcodes')")
barcode = cursor.fetchone()
The sequence is guaranteed to be unique. Note that there may be gaps in the generated numbers as rolling back the transaction will not "revert" advancing the sequence.
Now you have a guaranteed unique number, you can insert it into your barcode, guaranteeing its uniqueness as well.
For convenience, you may want to create / drop the sequence in a custom migration.