生成没有竞争条件的唯一条形码

Generate unique barcodes without race conditions

对于我们的客户,我需要生成唯一的条形码。任何客户不得拥有两个相同的条形码。条形码构建如下:

我想跟踪每个客户使用的最新索引号,并在生成条形码时检索最新索引号并将该索引号递增 1。

当两个进程尝试同时生成条形码时,现在会出现问题。进程 A 和 B 都询问最新的索引号,都收到相同的最新索引号并且都创建相同的条形码。

有没有办法确保即使在异步提供条码生成时,也不会生成重复的条码?构建它的系统是 Django 1.9,Python 3.5 和 PostgreSQL 数据库。

这是支持数据库引擎的工具之一,那么将它用于该目的如何?这是一个sequence。它与用于生成主键值的工具完全相同(我认为出于某种原因在您的情况下这不是一个选项,否则就使用它)。

不幸的是,它不是由 Django ORM 处理的,但你可以像这样直接创建一个:

CREATE SEQUENCE barcodes START WITH 100;

然后您可以随时通过从您的 Django 应用程序执行直接 SQL 查询来使用它:

from django.db import connection

with connection.cursor() as cursor:
    cursor.execute("select nextval('barcodes')")
    barcode = cursor.fetchone()

序列保证唯一。请注意,生成的数字中可能存在间隙,因为回滚事务不会 "revert" 推进序列。

现在您有了一个保证唯一的编号,您可以将它插入您的条形码,同时保证它的唯一性。

为方便起见,您可能希望在 custom migration.

中创建/删除序列