Asynchronous Sails findOrCreate returns“;“记录已存在”;如果异步运行

Asynchronous Sails findOrCreate returns“;“记录已存在”;如果异步运行,asynchronous,sails.js,waterline,Asynchronous,Sails.js,Waterline,使用sails.js,我有一个使用.findOrCreate(…)的服务 如果使用相同的数据同时调用此服务两次,它将返回“记录已存在”错误 这是一个已知的问题吗?有什么克服它的建议吗 更新: 我正在使用sails mysql。 查询字段被设置为唯一(这就是为什么我得到这个错误,否则会创建重复项),并且也被设置为索引(如中所建议) 更新2: Show.js: tmdbId: { type: 'integer', unique: true, index: true }, name: {

使用sails.js,我有一个使用.findOrCreate(…)的服务

如果使用相同的数据同时调用此服务两次,它将返回“记录已存在”错误

这是一个已知的问题吗?有什么克服它的建议吗

更新:

我正在使用sails mysql。
查询字段被设置为唯一(这就是为什么我得到这个错误,否则会创建重复项),并且也被设置为索引(如中所建议)

更新2:

Show.js:

tmdbId: {
  type: 'integer',
  unique: true,
  index: true
},
name: {
  type: 'string',
  required: true
},
slug: {
  type: 'string',
  required: true,
  unique: true
},
seasons: {
  collection: 'season',
  via: 'show'
},
episodes: {
  collection: 'episode',
  via: 'show'
}
服务:

Show.findOrCreate({
  tmdbId: req.tmdbId
}, {
  tmdbId: req.tmdbId,
  name: req.showName,
  slug: Services.slug(req.showName)
}).exec(function (err, show) {
  if (err)
    return sails.log.error(err);
  Season.findOrCreate({
    show: show.id,
    number: req.season
  }).exec(function (err, season) {
    if (err)
      return sails.log.error(err);
    Episode.findOrCreate({
      show: show.id,
      season: season.id,
      number: req.episode,
      airDate: req.airDate
    }).exec(function (err, episode) {
      if (err)
        return sails.log.error(err);
      return res;
    })
  })
})

您的
findOrCreate
不符合Sails惯例。尝试:

Show
    .findOrCreate({
      tmdbId: req.tmdbId
    }, {
      tmdbId: req.tmdbId,
      name: req.showName,
      slug: Services.slug(req.showName)
    })
    .exec(function (err, show) {
      if (err) return sails.log.error(err);

      Season
        .findOrCreate({
          show: show.id
        }, {
          show: show.id,
          number: req.season
        })
        .exec(function (err, season) {
          if (err) return sails.log.error(err);

          Episode
          .findOrCreate({
            show: show.id
          }, {
            show: show.id,
            season: season.id,
            number: req.episode,
            airDate: req.airDate
          })
          .exec(function (err, episode) {
            if (err) return sails.log.error(err);

            return res;
          })
        })
    })

我在postgres适配器上也遇到过同样的问题,我认为原因是比赛条件。这似乎是一个已知的问题:

findOrCreate
看起来不是原子的,因此我认为第一个调用执行一个
find
查询,该查询在执行创建操作之前不返回任何结果。如果第二个调用在第一个调用的
create
完成之前执行其
find
,它也会返回一个空结果,从而触发另一个
create

如果
create
数据包含唯一值,则会出现问题。由于执行了两个
create
操作,将添加两次相同的数据,因此第二个操作将失败,因为数据库中已存在唯一值。如果没有标记为
唯一的值
,则结果是重复的


解决此问题的一种方法是捕获错误,并在catch块中执行
find
查询,因为我们知道条目现在存在,然后是您打算首先执行的任何操作。但不幸的是,在您的示例中,这种方法确实变得非常丑陋,因为嵌套的
findOrCreate
调用需要各自的catch块。

您能写下您的查询吗?比如
Model.findOrCreate({id:1},{name:'some name'})