2017-04-17 55 views
0

我正在构建一个接收webhook数据(shopify订单)并将它们保存到关系型mysql数据库的api。每个订单都有属于集合(类别)的产品。我将产品与集合关联起来,或者如果它尚不存在,则创建一个新集合。我碰到的问题是,因为我不能使用findOrCreate()我首先做一个find(),然后如果没有找到,我做一个创建。然而,因为nodejs是异步的,所以如果我立刻得到很多订单,有时同一个集合不能同时被两个不同的产品找到,然后在另一个尝试之前创建它,所以当其他人尝试创建水线会引发错误:Sailsjs错误处理与数据库/水线错误

col_id •与col_id已存在的记录(405145674)。

什么是最好的方法来捕获这个错误,所以我可以做另一个find(),所以函数返回适当的集合,而不是一个未定义?我可以这样做:

if (err){ findmethodagain(); } 

但随后它会尝试任何错误,而不是一个“记录与该ID已经存在”的错误。

+0

尝试检查某些唯一代码或属性对于此类错误是唯一的错误,并仅在此类代码匹配时重试。 – Sangharsh

+0

@Sangharsh当我console.log它说错误是什么问题,但我不知道如何得到错误的某些部分。我应该做一个err.search('存在col_id alreasy存在的记录')还是相同的lodash? – hamncheez

+1

当错误被记录时,只显示'err.toString()'。检查err的其他属性,这些属性没有显示,但在这里很有用。例如。 err.toPOJO(),err.ValidationError,err.originalError,err.invalidAttributes – Sangharsh

回答

0

如果你没有看到这么多,延迟后再做第二次尝试也不会有什么坏处。例如,您可以使用Promise.delay(例如Bluebird)在出现任何错误后的几毫秒后运行第二个函数。如果在大多数情况下他们中的一个创建集合,那么只需一次重试即可成功。

如果您看到很多其他错误,那么修复它们。

但是,竞态条件通常表明您需要重新构建体系结构。我建议不要依赖错误属性或试图绕开它们,而是重新设计它,至少在需要创建新集合的情况下。一个普遍的选择是建立一个工作队列。在你的情况下,你只需在第一遍中使用find来查看是否存在一个集合,如果不存在,则将其启动到队列中以供单个工作人员依次选取。在工人的工作中,你的find然后创建。您可以使用RedisBull快速轻松地进行设置。