为工单生成唯一的序列号


generate unique serial numbers for shop order the doctrine way

我们使用 symfony2 构建了一个商店系统,它必须生成唯一的序列号。有一个订单实体最初具有属性orderNumber 订单实体是我们的"购物会话",因此不仅提交的订单会持久保存,而且每次用户放置 sth 时都会保留。进入他的购物车。订单编号为默认值 null,应仅在用户提交订单时设置。在普通的MySQL中,我会做sth。喜欢这个:

INSERT INTO orders (orderNumber, [...])
SELECT MAX(orderNumber) + 1, [...] FROM orders;

但是为了在理论上实现这一目标,我必须做一个表写锁,选择最大订单数,将其设置为排序实体,持久保存,然后解锁表。我不想这样做(表锁定的原因(,因此快速解决方法是踢 orderNumber 属性并仅将 id 显示为订单号。但这不是一个很好的解决方案,订单号有差距并且越来越高(4 个月后,我们的自动增量值为 140k,订单号不应超过 6 个字符,因此我们需要一个解决方案在遇到此限制之前(。

创建映射的超类并将 Order 实体拆分为单独的实体和表,用于临时订单和已提交的订单,将导致过多的代码更改。因此,下一个想法是创建一个具有自动增量字段的单独 OrderNumber 实体,并在用户提交订单时将其设置为 Order 实体。这似乎是一种无需太多更改即可做到这一点的方法。

但也许有更好的方法来解决这个问题,以教义的方式做到这一点的最佳解决方案是什么?

当自动增量用于订单号时,它被认为是电子商务中的一个缺点。原因是您的竞争对手可以轻松跟踪这些数字,并且或多或少知道您在一段时间内有多少订单。他们可以利用这些知识为自己谋取利益。这就是为什么我们公司要求生成随机订单号的原因。我们通过"加扰"从自动增量中检索到的 ID 来生成一个包含数字和字母的 6 个字符的标识符(当您使用字母时,您可以轻松地将超过 100 万个订单放入 6 个字符,支付网关应该可以与字母(。这是以确定性的方式完成的,因此可以将此数字转换回 ID(尽管这不是绝对必要的(。

您的解决方案带有单独的订单号表对我来说似乎很好。您还可以对orderNumber具有唯一约束,并生成随机数或随机数的哈希(种子应反映实际时间和用户会话 ID,以限制冲突概率(并尝试更新实体。如果失败,您将尝试重新生成。然后,您应该设置一个可以失败的最大次数,这样如果存在其他问题,它就不会永远循环。

在本演讲中描述了 教义 ORM 良好实践和技巧

我想建议你避免自动生成的标识符,因此使用UUID,而不是ramsey/uuid库。

因此,例如,您的订单实体可以类似于

 ......
/**
 * @ORM'Id
 * @Column(type="string")
 * @GeneratedValue(strategy="NONE")
 */
protected $id = null;
......
public function __construct()
{
    $this->id = Uuid::uuid4();
}

因此,在将其保留在数据库上之前,这是可访问的。

关于皮维塔(很棒!(谈话的更好灵感

希望这个帮助