【问题标题】:Generate unique barcodes without race conditions生成没有竞争条件的唯一条形码
【发布时间】:2016-08-17 11:24:21
【问题描述】:

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

  • 客户前缀
  • 索引号
  • 校验位

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

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

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

【问题讨论】:

  • 拥有超过 1000 分的你应该知道你需要发布你的 django 模型或你的 postgresql 表
  • 问题是我还没有任何模型/表格,我还在想一个解决方案如何做到这一点。
  • 这不是真正的话题吗?
  • 我不明白你的意思。我已经发布了我的问题描述,并提到了我正在使用的技术,我正在寻找可能的解决方案。
  • @physicalattraction> 除了下面的答案之外,如果您存储交易(我假设客户 ID + 索引号是诸如购买之类的交易),例如,对于日志记录,您可以只使用主要的交易的关键来跟踪它。

标签: python django postgresql barcode race-condition


【解决方案1】:

这是支持数据库引擎的工具之一,那么为此目的使用它怎么样?这是一个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()

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

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

为方便起见,您可能希望在 custom migration 中创建/删除序列。

【讨论】:

  • 编辑仍处于宽限期,但很重要:我更改了代码以正确处理光标。
  • 看起来不错,我会试一试并在这里更新我的发现。
  • @physicalattraction> 好的,但仍然考虑简单地使用“订单”模型并使用其主键生成条形码。您可以使用它来存储一些日志信息,例如交易时间等,并在稍后检查是否确实发布了某些条形码并且有人没有向您提供伪造的条形码。如果预计订单数量会成为问题,您总是可以定期修剪桌子。
  • 我现在已经用序列实现了这个方法,它似乎有效。 :-)
猜你喜欢
  • 2021-08-27
  • 2012-09-05
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多