同时生成唯一ID时避免冲突

时间:2020-01-30 15:55:36

标签: ruby-on-rails postgresql stripe-payments

我有一个Webhook来接收Stripe事件并相应地创建新发票。 根据当地法律,我必须自己生成发票编号,并且不能使用Stripe ID。这些是顺序的,唯一的ID。

当我同时从Stripe收到2个“新发票草稿”事件时,我遇到了一个并发问题。 这两个事件都生成了相同的发票编号,但是很自然,第二个事件无法插入PostgreSQL数据库中,Stripe稍后重试。

发票编号基本上如下所示:YYYY-XXXXX,其中YYYY是年份,而XXXXX是序列号,从年份的第一张发票的00001开始。如果最后一个数字是2020-00017,那么下一个数字只能是2020-00018。

所以这有点奏效,但似乎并不理想。 您知道有什么比让Stripe重试更好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

我认为让Stripe重试可能是最好的选择,因为它已经实现并经过了测试。如果有人画了下一个数字,那么直到他们实际完成之后,才能知道他们是否要提交。因此,您需要失败并重试,或者阻止并等待,或者采用下一个数字,如果前一个数字失败,则允许间隔。重试是否有问题,还是您发现它不整洁?如果有问题,那是什么?在不知道旧问题出在哪里的情况下,很难设计出一种新的解决方案。

答案 1 :(得分:1)

存在一些满足此要求的选项。

如@jjanes所述,您可以返回HTTP状态代码> 2XX状态代码,这将导致Stripe重试该请求。如果您希望重复的次数很少,那很好,但是如果您希望快速扩展并经常使用> 200个错误代码进行响应,那么我将在您的后端中建立重试和串行处理逻辑。

例如,您可以将事件数据推送到队列中,然后立即以200状态代码进行响应。然后在后台作业中按队列顺序处理事件。这样一来,您就可以编写自己的逻辑来对ID进行重复数据删除,确保它们是连续的,并避免禁用Stripe上的Webhook端点的风险(用于响应200多个状态代码的响应)。