-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MongoError: writeConcern is not allowed within a multi-statement transaction #11382
Comments
I think there is an issue with bulkWrite as code works fine without it, even if promise array contains only bulkWrite promise - it fails with same error... |
Is an Upgrade to v6 not an alternative? |
I'm getting same error when i updated to 6.2.1 version. |
I think this is maybe connected with one bug I reported. |
Thanks, it works if i execute promises in serial inside withTransaction. However i haven't noticed that somebody forbidden parallel operations. I think something might be wrong with concurrency and transactions not mongoose but in mongo driver itself, so i will keep it opened... |
Yes this is a common issue in mongodb, as it seems that all drivers are effected. We could theoretically avoid this by doing some no op operation in transaction when using mongoose specific transaction helper. But on the other hand it would slow down the whole transaction even if you don't have the issue of parallel db operations like when you know what you are doing. Probably mongo wants to optimize the database transactions and the locks by starting them actually with the first transaction related operation. We could kind of track in mongoose specific transaction wrapper that if we are in transactions that we buffer the operations and run the first operation in session separately and delay the rest till the first operation in session is done. Maybe @vkarpov15 has some idea on this. |
I'm unable to repro this, the below script executes without error. Please modify the below script to demonstrate the issue you're seeing. 'use strict';
const mongoose = require('mongoose');
mongoose.set('debug', true);
const { Schema } = mongoose;
run().catch(err => console.log(err));
async function run() {
await mongoose.connect('mongodb://localhost:27017,localhost:27018/test?replicaSet=rs&w=majority&wtimeout=15000', { autoCreate: true });
await mongoose.connection.dropDatabase();
const schema = new Schema({ name: String });
const Model = mongoose.model('Test', schema);
await Model.init();
const session = await mongoose.startSession();
await session.withTransaction(async function() {
await Promise.all([
Model.updateOne({}, { name: 'test' }, { session }),
Model.bulkWrite([
{
insertOne: {
document: {
name: 'Eddard Stark',
title: 'Warden of the North'
}
}
},
], { session })
]);
});
await session.endSession();
console.log('Done', await Model.findOne());
} |
@vkarpov15 This is an old issue, but I am commenting because I reproduced the error. Although different from the original code, the following code results in an error. 'use strict';
const mongoose = require('mongoose');
mongoose.set('debug', true);
const { Schema } = mongoose;
run().catch(err => console.log(err));
async function run() {
await mongoose.connect('mongodb://localhost:27017,localhost:27018/test?replicaSet=rs&w=majority&wtimeout=15000', { autoCreate: true });
await mongoose.connection.dropDatabase();
const schema = new Schema({ name: String }, { writeConcern: { w: 'majority' }});
const Model = mongoose.model('Test', schema);
await Model.init();
const session = await mongoose.startSession();
await session.withTransaction(async function() {
await Promise.all([
Model.findOneAndUpdate({}, { name: 'test' }, { session }),
Model.bulkWrite([
{
insertOne: {
document: {
name: 'Eddard Stark',
title: 'Warden of the North'
}
}
},
], { session })
]);
});
await session.endSession();
console.log('Done', await Model.findOne());
} @@ -13,7 +13,7 @@
await mongoose.connection.dropDatabase();
- const schema = new Schema({ name: String });
+ const schema = new Schema({ name: String }, { writeConcern: { w: 'majority' }});
const Model = mongoose.model('Test', schema);
await Model.init();
@@ -21,7 +21,7 @@
await session.withTransaction(async function() {
await Promise.all([
- Model.updateOne({}, { name: 'test' }, { session }),
+ Model.findOneAndUpdate({}, { name: 'test' }, { session }),
Model.bulkWrite([
{
insertOne: { With the Schema option set to writeConsern, if there is a findOneAndUpdate in the transaction, it is an error. If updateOne, it is not an error. |
fix(schema): avoid applying default write concern to operations that are in a transaction
Hi!
I have 5.13.14 mongoose.
My rs db connection string contains retryWrites=true&w=majority&wtimeout=15000
My code looks like this:
It throws
Why? Does mongoose apply write concern for single operation even if they are run in session?
Would be grateful if you could help.
The text was updated successfully, but these errors were encountered: