gpt4 book ai didi

javascript - 为什么 insertmany 不能使用 mongoos 进行事务处理?

转载 作者:行者123 更新时间:2023-12-01 00:35:50 26 4
gpt4 key购买 nike

我正在尝试使用 inertMany 插入数据。但是我无法插入数据,为什么?我正在使用 mongoose session 如果发生任何错误,我会回滚变化

https://codesandbox.io/s/dreamy-bell-9u0bz

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 session.commitTransaction();
return res.send(saveBlog);
} catch (error) {
console.log(error);
await session.abortTransaction();
return res.status(400).send(error);
}
});

最佳答案

因为您似乎没有理解 marked duplicatecomment 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 session.commitTransaction();
} 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
}
]
}

请注意,当使用事务时,没有任何项目插入到集合中。使用默认行为为 ordered: trueinsertMany() 将插入所有批量项目,直到遇到任何错误。 p>

请注意,由于您确实期望出现错误,因此您必须在其自己的try..catch中包含这样的语句,或者类似的错误处理程序。否则,任何错误(在示例情况下是预期的)都会简单地落入外部catch,当然在演示中它只是退出程序。

<小时/>

实际上并不是在问题本身中,而是在How to use MongoDB transaction using Mongoose?的演示中实际上没有提到的东西。事实上,您应该意识到,当交易处于事件状态时,您必须还包括任何上的session属性后续读取以便查看该事务中所做的更改。

例如,以下内容不会显示集合中的任何内容:

let session = await conn.startSession();
session.startTransaction();

try {
await BlogPost.insertMany(sampleData, { session });
let documents = await BlogPost.find(); // This would return nothing
await session.commitTransaction();
} catch(e) {
// Show the error and abort
log({ err: e.errmsg, result: e.result.result.writeErrors });
await session.abortTransaction();
}

但是,在 find() 中包含 session 将实际显示插入的内容:

try {
await BlogPost.insertMany(sampleData, { session });
// Actually includes the session and therefore the state
let documents = await BlogPost.find({},{ session });

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

当然,在这种情况下,读取将取决于 insertMany() 不会因任何原因失败,因为任何错误都会导致在发出下一个请求之前退出到 catch

一旦事务被提交,它当然可用于连接的全局状态。但是,虽然正在进行,但只有包含启动事务的相同 session 信息的操作才能看到该事务中实现的任何更改。

关于javascript - 为什么 insertmany 不能使用 mongoos 进行事务处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58144439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com