diff --git a/lib/plugins/trackTransaction.js b/lib/plugins/trackTransaction.js index af5c7c84da4..857caac6044 100644 --- a/lib/plugins/trackTransaction.js +++ b/lib/plugins/trackTransaction.js @@ -27,13 +27,6 @@ module.exports = function trackTransaction(schema) { initialState.atomics = _getAtomics(this); session[sessionNewDocuments].set(this, initialState); - } else { - const state = session[sessionNewDocuments].get(this); - - for (const path of Object.keys(this.$__.activePaths.getStatePaths('modify'))) { - state.modifiedPaths.add(path); - } - state.atomics = _getAtomics(this, state.atomics); } }); }; diff --git a/test/docs/transactions.test.js b/test/docs/transactions.test.js index de2ecfc9952..2a63f07a984 100644 --- a/test/docs/transactions.test.js +++ b/test/docs/transactions.test.js @@ -565,6 +565,57 @@ describe('transactions', function() { assert.equal(i, 3); }); + it('transaction() avoids duplicating atomic operations (gh-14848)', async function() { + db.deleteModel(/Test/); + const subItemSchema = new mongoose.Schema( + { + name: { type: String, required: true } + }, + { _id: false } + ); + const itemSchema = new mongoose.Schema( + { + name: { type: String, required: true }, + subItems: { type: [subItemSchema], required: true } + }, + { _id: false } + ); + const schema = new mongoose.Schema({ + items: { type: [itemSchema], required: true } + }); + const Test = db.model('Test', schema); + + + await Test.createCollection(); + await Test.deleteMany({}); + + const { _id } = await Test.create({ + items: [ + { name: 'test1', subItems: [{ name: 'x1' }] }, + { name: 'test2', subItems: [{ name: 'x2' }] } + ] + }); + + let doc = await Test.findById(_id); + + doc.items.push({ name: 'test3', subItems: [{ name: 'x3' }] }); + + let i = 0; + await db.transaction(async(session) => { + await doc.save({ session }); + if (++i < 3) { + throw new mongoose.mongo.MongoServerError({ + errorLabels: ['TransientTransactionError'] + }); + } + }); + + assert.equal(i, 3); + + doc = await Test.findById(_id); + assert.equal(doc.items.length, 3); + }); + it('doesnt apply schema write concern to transaction operations (gh-11382)', async function() { db.deleteModel(/Test/); const Test = db.model('Test', Schema({ status: String }, { writeConcern: { w: 'majority' } })); diff --git a/test/document.test.js b/test/document.test.js index d368246c133..6a5765fe116 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -8177,14 +8177,14 @@ describe('document', function() { await person.save(); }); - it('set() merge option with double nested', async function () { + it('set() merge option with double nested', async function() { const PersonSchema = new Schema({ info: { address: { city: String, - country: { type: String, default: "UK" }, + country: { type: String, default: 'UK' }, postcode: String - }, + } } }); @@ -8194,19 +8194,19 @@ describe('document', function() { const person = new Person({ info: { address: { - country: "United States", - city: "New York" - }, + country: 'United States', + city: 'New York' + } } }); - const update = { info: { address: { postcode: "12H" } } }; + const update = { info: { address: { postcode: '12H' } } }; person.set(update, undefined, { merge: true }); - - assert.equal(person.info.address.city, "New York"); - assert.equal(person.info.address.postcode, "12H"); - assert.equal(person.info.address.country, "United States"); + + assert.equal(person.info.address.city, 'New York'); + assert.equal(person.info.address.postcode, '12H'); + assert.equal(person.info.address.country, 'United States'); }); it('setting single nested subdoc with timestamps (gh-8251)', async function() {