swf*_*u69 2 javascript transactions mongoose mongodb node.js
旁注我使用以下代码连接到数据库:
const mongoose = require('mongoose');
const connectDB = (url) => {
return mongoose.connect(url);
}
Run Code Online (Sandbox Code Playgroud)
问题描述:
我有两个不同的集合。这两个操作,findByIdAndUpdate并且create必须作为原子操作运行。这对于猫鼬交易来说应该是可能的。
const registerCustomer = async (req, res) => {
await CustomerRegistrationCode.findByIdAndUpdate(req.body._id, { used: true });
const customer = await Customer.create({firstName: req.body.firstName});
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的:
const registerCustomer = async (req, res) => {
const session = await mongoose.startSession();
await session.startTransaction();
try {
await CustomerRegistrationCode.findByIdAndUpdate(req.body._id, { used: true }); //updates even though
const customer = await Customer.create({ firstName: req.body.firstName });// this line will throw error
await session.commitTransaction();
session.endSession();
} catch (error) {
console.error('abort transaction');
await session.abortTransaction();
session.endSession();
throw error;
}
}
Run Code Online (Sandbox Code Playgroud)
问题即使 Customer.create 方法抛出错误,CustomerRegistrationCode 集合也会更新。如何解决这个问题?
理解 MongoDB 事务的新方法失败了,但这是来自https://mongoosejs.com/docs/transactions.html的官方代码
const mongoose = require('mongoose');
const debugMongo = async () => {
const db = await mongoose.createConnection("mongodb://localhost:27017/mongotest");
const Customer = db.model('Customer', new mongoose.Schema({ name: String }));
const session = await db.startSession();
session.startTransaction();
await Customer.create([{ name: 'Test' }], { session: session }); //(node:20416) UnhandledPromiseRejectionWarning: MongoServerError: Transaction numbers are only allowed on a replica set member or mongos
let doc = await Customer.findOne({ name: 'Test' });
assert.ok(!doc);
doc = await Customer.findOne({ name: 'Test' }).session(session);
assert.ok(doc);
await session.commitTransaction();
doc = await Customer.findOne({ name: 'Test' });
assert.ok(doc);
session.endSession();
}
debugMongo();
Run Code Online (Sandbox Code Playgroud)
抛出Customer.create错误,我不知道为什么。有人有一个最小的工作示例吗?
Ayz*_*ian 10
您以错误的方式使用交易,这就是它不起作用的原因。
您需要将该session对象传递给您的操作。
const registerCustomer = async (req, res) => {
const session = await mongoose.startSession();
session.startTransaction();
try {
await CustomerRegistrationCode.findByIdAndUpdate(req.body._id, { used: true }, { session });
const customer = await Customer.create({ firstName: req.body.firstName }, { session });
await session.commitTransaction();
} catch (error) {
console.error('abort transaction');
await session.abortTransaction();
} finally {
session.endSession();
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我对你的代码进行了一些重构。