0

我在正确编写 Cloud SQL 和 Google App Engine 时遇到问题。将 NoSQL 与 Cloud SQL 和 Google App Engine 一起使用来写入数据库,我设法建立了连接——这太棒了!

唯一的问题是,当我为应用程序运行插入函数时,insertVisit(knex, visit)单个调用有多个写入。这是所有相关代码。

应用程序.js

//Connecting to the NoSQL Cloud SQL database, and using Knex to do all database-y things. 

const knex = connect();

function connect () {   
  const config = {
      socketPath: "/cloudsql/<INSTANCE_CONNECTION_NAME>",
      user: "USERNAME",
      password: "PASSWORD",
      database: "DATABASE"
  };

  // Connect to the database
  const knex = Knex({
    client: 'mysql',
    connection: config
  });

  return knex;
}

function insertVisit (knex, visit) {
      return knex('user_visits').insert(visit);
    }
}

function getVisits (knex) {
  return knex.select().table('user_visits').pluck('visits')
}

App Engine 结局

app.get('/new_visit', (req, res, next) => {

  // Create a visit record to be stored in the database
  const visit = {
    visits: new Date()
  }

  insertVisit(knex, visit)
    // return a response
    .then(() => {
      res
        .status(200)
        .set('Content-Type', 'text/plain')
        .send(`successfully created.`)
        .end();
    })
    .catch((err) => {
      next(err);
    });
});

app.get('/see_visits', (req, res, next) => {
  getVisits(knex)
  .then( (visits) => {
    res
        .status(200)
        .set('Content-Type', 'text/plain')
        .send(`Last 10 visits:\n${visits.join('\n')}`)
        .end();
  })
})

我一切都很好。但是当我访问new_visit一次时,see_visits我会期待网页上的回复,比如:

Last 10 Visits: 

Aug 10 12:34:56 
Aug 11 23:11:45 

相反,我知道正在发生两次(或三次)呼叫,因为我得到:

Last 10 Visits: 

Aug 10 12:34:56
Aug 10 12:34:57
Aug 10 12:34:57
Aug 11 23:11:45
Aug 11 23:11:46

相关的app.yaml字段如下:

manual_scaling:
  instances: 1
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

这是谷歌的默认建议。

有没有人有任何见解或......任何关于我可以做些什么来防止这些双重,三重写入发生的知识?如果每次我尝试向表中插入更多信息时都在写入重复数据,那将是口袋里的一个大洞。

4

1 回答 1

0

简单的解决方案是使用Google Analytics之类的东西,它只需要您在前端插入 4 行 javascript,并且会提供比自制解决方案更可靠的信息。

如果您绝对需要自己做某事,则必须将时间戳与某种可识别的 id 配对。否则,页面的每次刷新都会为您提供一个新条目。然后在插入数据库时​​,使用原始 SQL 并添加ON DUPLICATE KEY UPDATE到末尾INSERT(Knex 目前不通过 ORM 支持此功能 - 请参见此处。)

对于您使用的 ID,请远离使用 IP 地址 - 来自同一网络的人们将共享一个 IP,这意味着您将删除您不想要的访问重复数据。相反,我建议生成一个UUID并将其存储在用户的 cookie 中。

于 2019-04-04T16:30:33.273 回答