mongoose下高并发,数据可靠吗?
发布于 3 个月前 作者 axetroy 659 次浏览 来自 问答

假设数据表中存放一个document

{
  "num": 0
}

请求一次接口, 则调用mongoose,让num+1

请求1000次

const axios = require('axios');

for (let i = 0; i < 1000; i++) {
  (i => {
    axios
      .get(
        'http://localhost:3000/test/update/0f9c4a32-6170-402b-828f-8e81b398dfb1'
      )
      .then(data => {
        console.log(`${i}: ${data.data.num}`);
      })
      .catch(function(err) {});
  })(i);
}

718: 3 743: 3 768: 3 793: 3 818: 3 843: 3 868: 3 893: 3 918: 3 943: 3 968: 3 993: 3 957: 3 982: 3 946: 3 947: 3 972: 3 997: 3

可以看到,结果并不像相信中的数字

而nodejs也没有进程锁,求解?

这是mongodb的特性,还是mongosse的?

参考: https://github.com/Automattic/mongoose/issues/4004 https://github.com/Automattic/mongoose/issues/5424

9 回复

敖德萨多撒

@newming 发送到发送到发送到

你姿势不对。使用$inc

@AnzerWall 求教正确的使用姿势。

逻辑是这样的

export async function increase(id: string) {
  const doc: any = await TestModal.findOne({ id });
  if (!doc) {
    throw new Error(`Invalid id`);
  }
  doc.num = doc.num + 1;
  await doc.save();
  return RFC3339NanoMaper(doc.toJSON());
}

我想就是因为异步读取数据,那时候数据还没有更改,老是读到旧数据,然后旧数据+1,又存储。

才有有这样的问题

export async function increase(id: string) { const doc: any = await TestModal.findOneAndUpdate({ id }, { $inc :{ num: 1 } }, { new: true }); return RFC3339NanoMaper(doc.toJSON()); } mongoose的语法有点忘了,大概这样

@AnzerWall 看了一下文档,知道是这么用了。

可以$inc只是针对数字,$increase用于自增

可是更改字符串呢?

{ $inc: { num: 1, "0.8679921263662924" } }

{ error: [ { message: ‘Cannot increment with non-numeric argument: {val: “0.8679921263662924”}’ } ] }

实际的业务情况,都不是自增++那么简单

请教还有其他的方法吗

暂时没有可行办法。

幸好Postgres救我狗命

回到顶部