为商店订单生成唯一的序列号学说方式

时间:2016-02-16 10:50:47

标签: php symfony doctrine-orm doctrine-query

我们使用doctrine建立了一个使用symfony2的商店系统,该系统必须生成唯一的序列号。 有一个Order实体,最初有一个属性orderNumber Order实体是我们的“购物会话”,因此不仅提交的订单是持久的,而且每次用户放置时都是如此。进入他的购物车。 orderNumber是默认值null,只应在用户提交订单时设置。 在普通的MySQL我会做的......像这样:

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

但要在学说中实现这一点,我必须做一个表写锁,选择max orderNumber,将其设置为order entity,persist然后解锁表。我不想那样做(表锁的原因)所以快速的解决方法是踢orderNumber属性,只显示id作为订单号。 但这不是一个好的解决方案,订单数量有差距并且越来越高(4个月后我们的自动增量值为140k,订单号不应超过6个字符,所以我们需要一个解决方案才能遇到这个问题极限)。

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

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

已在此演示文稿Doctrine ORM Good Practices and Tricks

中进行了描述

我建议您避免使用自动生成的标识符,以便使用UUID代替ramsey/uuid Library

因此,作为示例,您的订单实体可能与

类似
 ......
/**
 * @ORM\Id
 * @Column(type="string")
 * @GeneratedValue(strategy="NONE")
 */
protected $id = null;

......

public function __construct()
{
    $this->id = Uuid::uuid4();
}

因此,在将其保留在数据库中之前,可以访问它。

Pivetta的(伟大!)谈话更好的灵感

希望这个帮助