最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

为什么insertmany无法在事务中使用mongoos?

IT培训 admin 8浏览 0评论

为什么insertmany无法在事务中使用mongoos?

[我试图使用inertMany插入数据。但是为什么我不能插入数据?如果发生任何错误,我就使用mongoose session,然后回滚更改

app.get("/saveData", async (req, res, next) => {
  const session = await mongoose.startSession();
  session.startTransaction();
  try {
    const data = [
      {
        empid: "Ad",
        id: 4,
        date: "19-Jul-2019"
      },
      {
        empid: "Bc",
        id: 56,
        date: "18-Jul-2019"
      },

      {
        empid: "C",
        id: 6,
        date: "11-Jul-2019"
      }
    ];
    console.log("before save");
    let saveBlog = await BlogPostModel.insertMany(data, { session }); //when fail its goes to catch
    await sessionmitTransaction();
    return res.send(saveBlog);
  } catch (error) {
    console.log(error);
    await session.abortTransaction();
    return res.status(400).send(error);
  }
});
回答如下:

由于您似乎不太了解marked duplicate或comment on your last question,因此直接演示:

const { Schema } = mongoose = require('mongoose');

const uri = 'mongodb://localhost:27017/test';
const opts = { useNewUrlParser: true, useUnifiedTopology: true };

mongoose.Promise = global.Promise;

mongoose.set('debug', true);
mongoose.set('useCreateIndex', true);
mongoose.set('useFindAndModify', false);

const blogPostSchema = new Schema({
  id: { type: Number, unique: true },
  empid: String,
  date: Date
});

const BlogPost = mongoose.model('BlogPost', blogPostSchema);

const sampleData = [
  { empid: "test13", id: 6, date: '11-Jul-2019' },
  { empid: "test123", id: 4, date: '19-Jul-2019' },
  { empid: "test13", id: 4, date: '18-Jul-2019' }
];

const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() {

  try {
    const conn = await mongoose.connect(uri, opts);

    // Clean data
    await Promise.all(
      Object.values(conn.models).map(m => m.deleteMany())
    );

    // Collections must existi in transactions
    await Promise.all(
      Object.values(conn.models).map(m => m.createCollection())
    );


    // With Transaction
    log("With Transaction");
    let session = await conn.startSession();
    session.startTransaction();

    try {
      await BlogPost.insertMany(sampleData, { session });
      await sessionmitTransaction();
    } catch(e) {
      // Show the error and abort
      log({ err: e.errmsg, result: e.result.result.writeErrors });
      await session.abortTransaction();
    }

    log({ results: (await BlogPost.find()) });

    // No transaction
    log("Without Transaction");
    try {
      await BlogPost.insertMany(sampleData);
    } catch(e) {
      // Show the error
      log({ err: e.errmsg, result: e.result.result.writeErrors });
    }

    log({ results: (await BlogPost.find()) });


  } catch (e) {
    console.error(e);
  } finally {
    mongoose.disconnect();
  }


})();

和输出:

Mongoose: blogposts.createIndex({ id: 1 }, { unique: true, background: true })
Mongoose: blogposts.deleteMany({}, {})
"With Transaction"
Mongoose: blogposts.insertMany([ { _id: 5d8f28ac462a1e1a8c6838a2, empid: 'test13', id: 6, date: 2019-07-10T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a3, empid: 'test123', id: 4, date: 2019-07-18T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a4, empid: 'test13', id: 4, date: 2019-07-17T14:00:00.000Z, __v: 0 } ], { session: ClientSession("650da06d23544ef8bc1d345d93331d1e") })
{
  "err": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
  "result": [
    {
      "code": 11000,
      "index": 2,
      "errmsg": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
      "op": {
        "_id": "5d8f28ac462a1e1a8c6838a4",
        "empid": "test13",
        "id": 4,
        "date": "2019-07-17T14:00:00.000Z",
        "__v": 0
      }
    }
  ]
}
Mongoose: blogposts.find({}, { projection: {} })
{
  "results": []
}
"Without Transaction"
Mongoose: blogposts.insertMany([ { _id: 5d8f28ac462a1e1a8c6838a5, empid: 'test13', id: 6, date: 2019-07-10T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a6, empid: 'test123', id: 4, date: 2019-07-18T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a7, empid: 'test13', id: 4, date: 2019-07-17T14:00:00.000Z, __v: 0 } ], {})
{
  "err": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
  "result": [
    {
      "code": 11000,
      "index": 2,
      "errmsg": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
      "op": {
        "_id": "5d8f28ac462a1e1a8c6838a7",
        "empid": "test13",
        "id": 4,
        "date": "2019-07-17T14:00:00.000Z",
        "__v": 0
      }
    }
  ]
}
Mongoose: blogposts.find({}, { projection: {} })
{
  "results": [
    {
      "_id": "5d8f28ac462a1e1a8c6838a5",
      "empid": "test13",
      "id": 6,
      "date": "2019-07-10T14:00:00.000Z",
      "__v": 0
    },
    {
      "_id": "5d8f28ac462a1e1a8c6838a6",
      "empid": "test123",
      "id": 4,
      "date": "2019-07-18T14:00:00.000Z",
      "__v": 0
    }
  ]
}

请注意,在使用交易记录时,没有任何项目插入集合中。将insertMany()与默认行为ordered: true一起使用将插入所有batched项目,直到遇到任何错误为止。

也请注意,因为您确实期望错误,所以必须在自己的try..catch或类似的错误处理程序中包含这样的语句。否则,任何错误(在示例情况下是预期的)都将简单地落在outer catch上,当然,在演示中,这只是退出程序。

为什么insertmany无法在事务中使用mongoos?

[我试图使用inertMany插入数据。但是为什么我不能插入数据?如果发生任何错误,我就使用mongoose session,然后回滚更改

app.get("/saveData", async (req, res, next) => {
  const session = await mongoose.startSession();
  session.startTransaction();
  try {
    const data = [
      {
        empid: "Ad",
        id: 4,
        date: "19-Jul-2019"
      },
      {
        empid: "Bc",
        id: 56,
        date: "18-Jul-2019"
      },

      {
        empid: "C",
        id: 6,
        date: "11-Jul-2019"
      }
    ];
    console.log("before save");
    let saveBlog = await BlogPostModel.insertMany(data, { session }); //when fail its goes to catch
    await sessionmitTransaction();
    return res.send(saveBlog);
  } catch (error) {
    console.log(error);
    await session.abortTransaction();
    return res.status(400).send(error);
  }
});
回答如下:

由于您似乎不太了解marked duplicate或comment on your last question,因此直接演示:

const { Schema } = mongoose = require('mongoose');

const uri = 'mongodb://localhost:27017/test';
const opts = { useNewUrlParser: true, useUnifiedTopology: true };

mongoose.Promise = global.Promise;

mongoose.set('debug', true);
mongoose.set('useCreateIndex', true);
mongoose.set('useFindAndModify', false);

const blogPostSchema = new Schema({
  id: { type: Number, unique: true },
  empid: String,
  date: Date
});

const BlogPost = mongoose.model('BlogPost', blogPostSchema);

const sampleData = [
  { empid: "test13", id: 6, date: '11-Jul-2019' },
  { empid: "test123", id: 4, date: '19-Jul-2019' },
  { empid: "test13", id: 4, date: '18-Jul-2019' }
];

const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() {

  try {
    const conn = await mongoose.connect(uri, opts);

    // Clean data
    await Promise.all(
      Object.values(conn.models).map(m => m.deleteMany())
    );

    // Collections must existi in transactions
    await Promise.all(
      Object.values(conn.models).map(m => m.createCollection())
    );


    // With Transaction
    log("With Transaction");
    let session = await conn.startSession();
    session.startTransaction();

    try {
      await BlogPost.insertMany(sampleData, { session });
      await sessionmitTransaction();
    } catch(e) {
      // Show the error and abort
      log({ err: e.errmsg, result: e.result.result.writeErrors });
      await session.abortTransaction();
    }

    log({ results: (await BlogPost.find()) });

    // No transaction
    log("Without Transaction");
    try {
      await BlogPost.insertMany(sampleData);
    } catch(e) {
      // Show the error
      log({ err: e.errmsg, result: e.result.result.writeErrors });
    }

    log({ results: (await BlogPost.find()) });


  } catch (e) {
    console.error(e);
  } finally {
    mongoose.disconnect();
  }


})();

和输出:

Mongoose: blogposts.createIndex({ id: 1 }, { unique: true, background: true })
Mongoose: blogposts.deleteMany({}, {})
"With Transaction"
Mongoose: blogposts.insertMany([ { _id: 5d8f28ac462a1e1a8c6838a2, empid: 'test13', id: 6, date: 2019-07-10T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a3, empid: 'test123', id: 4, date: 2019-07-18T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a4, empid: 'test13', id: 4, date: 2019-07-17T14:00:00.000Z, __v: 0 } ], { session: ClientSession("650da06d23544ef8bc1d345d93331d1e") })
{
  "err": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
  "result": [
    {
      "code": 11000,
      "index": 2,
      "errmsg": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
      "op": {
        "_id": "5d8f28ac462a1e1a8c6838a4",
        "empid": "test13",
        "id": 4,
        "date": "2019-07-17T14:00:00.000Z",
        "__v": 0
      }
    }
  ]
}
Mongoose: blogposts.find({}, { projection: {} })
{
  "results": []
}
"Without Transaction"
Mongoose: blogposts.insertMany([ { _id: 5d8f28ac462a1e1a8c6838a5, empid: 'test13', id: 6, date: 2019-07-10T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a6, empid: 'test123', id: 4, date: 2019-07-18T14:00:00.000Z, __v: 0 }, { _id: 5d8f28ac462a1e1a8c6838a7, empid: 'test13', id: 4, date: 2019-07-17T14:00:00.000Z, __v: 0 } ], {})
{
  "err": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
  "result": [
    {
      "code": 11000,
      "index": 2,
      "errmsg": "E11000 duplicate key error collection: test.blogposts index: id_1 dup key: { id: 4 }",
      "op": {
        "_id": "5d8f28ac462a1e1a8c6838a7",
        "empid": "test13",
        "id": 4,
        "date": "2019-07-17T14:00:00.000Z",
        "__v": 0
      }
    }
  ]
}
Mongoose: blogposts.find({}, { projection: {} })
{
  "results": [
    {
      "_id": "5d8f28ac462a1e1a8c6838a5",
      "empid": "test13",
      "id": 6,
      "date": "2019-07-10T14:00:00.000Z",
      "__v": 0
    },
    {
      "_id": "5d8f28ac462a1e1a8c6838a6",
      "empid": "test123",
      "id": 4,
      "date": "2019-07-18T14:00:00.000Z",
      "__v": 0
    }
  ]
}

请注意,在使用交易记录时,没有任何项目插入集合中。将insertMany()与默认行为ordered: true一起使用将插入所有batched项目,直到遇到任何错误为止。

也请注意,因为您确实期望错误,所以必须在自己的try..catch或类似的错误处理程序中包含这样的语句。否则,任何错误(在示例情况下是预期的)都将简单地落在outer catch上,当然,在演示中,这只是退出程序。

发布评论

评论列表 (0)

  1. 暂无评论