Postgres承诺多个查询 – nodejs

阅读https://stackoverflow.com/a/14797359/4158593之后 :关于nodejs单线程,并且它需要asynchronous函数的第一个参数,处理它,然后使用callback来响应,当一切准备就绪。 我困惑的是,如果我有多个查询需要一次性完成,并告诉nodeJS通过将其添加到队列中来阻止其他请求。

为了做到这一点,我意识到我需要在另一个callback包装我的查询。 承诺做得很好。

  const psqlClient = psqlPool.connect(); return psqlClient.query(`SELECT username FROM usernames WHERE username=$1`, ['me']) .then((data) => { if(!data.rows[0].username) { psqlClient.query(`INSERT INTO usernames (username) VALUES ('me')`); } else { ... } }); 

在注册过程中使用此代码来检查在插入之前是否未使用用户名。 因此,nodejs将其他请求放入队列非常重要,并确保同时selectinsert 。 由于此代码可能允许同时发送同一用户名的用户select已被使用的用户名,因此将插入两个用户名。

问题

  1. 上面的代码是否一次执行查询?

  2. 如果1是正确的,如果我要改变这样的代码

     const psqlClient = psqlPool.connect(); return psqlClient.query(`SELECT username FROM usernames WHERE username=$1`, ['me'], function(err, reply) { if(!reply.rows[0].username) { psqlClient.query(`INSERT INTO usernames (username) VALUES ('me')`); } }); 

    会影响行为吗?

  3. 如果1错了,应该如何解决? 我将需要这种模式(主要是使用selectinsert/update一个接一个),如确保我的XML站点地图不包含超过50000个URL,通过为我的数据库中的每个文件存储计数dynamic发生。

唯一可以保证数据完整性的是一个SELECT->INSERT查询,在这里已经讨论了很多次。

一些例子:

  • SELECT或INSERT在一个容易出现竞争条件的函数中?
  • 从条件INSERT获取ID

你应该可以在这里find更多的;)


我也在pg-promise的 SELECT⇒INSERT例子中谈到了这个问题。


然而,有一个替代scheme,使任何重复插入产生冲突,在这种情况下,您可以重新运行您的select获取新的logging。 但这并不总是一个合适的解决scheme。

以下是node-postgres的创build者的参考: https : //github.com/brianc/node-postgres/issues/83#issuecomment-212657287 。 基本上查询排队,但不要依赖于他们在生产中,你有很多要求….

但是,您可以使用BEGINCOMIT

 var Client = require('pg').Client; var client = new Client(/*your connection info goes here*/); client.connect(); var rollback = function(client) { //terminating a client connection will //automatically rollback any uncommitted transactions //so while it's not technically mandatory to call //ROLLBACK it is cleaner and more correct client.query('ROLLBACK', function() { client.end(); }); }; client.query('BEGIN', function(err, result) { if(err) return rollback(client); client.query('INSERT INTO account(money) VALUES(100) WHERE id = $1', [1], function(err, result) { if(err) return rollback(client); client.query('INSERT INTO account(money) VALUES(-100) WHERE id = $1', [2], function(err, result) { if(err) return rollback(client); //disconnect after successful commit client.query('COMMIT', client.end.bind(client)); }); }); }); 

签出: https : //github.com/brianc/node-postgres/wiki/Transactions

但是这并不妨碍表格。 这里有一个解决scheme列表: 更新哪里比赛条件Postgres(阅读提交)