diff --git a/lib/model.js b/lib/model.js index 56168cccb72..052414d2b76 100644 --- a/lib/model.js +++ b/lib/model.js @@ -356,7 +356,7 @@ Model.prototype.$__handleSave = function(options, callback) { const optionsWithCustomValues = Object.assign({}, options, saveOptions); const where = this.$__where(); const optimisticConcurrency = this.$__schema.options.optimisticConcurrency; - if (optimisticConcurrency) { + if (optimisticConcurrency && !Array.isArray(optimisticConcurrency)) { const key = this.$__schema.options.versionKey; const val = this.$__getValue(key); if (val != null) { @@ -718,7 +718,15 @@ Model.prototype.$__delta = function() { const optimisticConcurrency = this.$__schema.options.optimisticConcurrency; if (optimisticConcurrency) { - this.$__.version = dirty.length ? VERSION_ALL : VERSION_WHERE; + if (Array.isArray(optimisticConcurrency)) { + const optCon = new Set(optimisticConcurrency); + const modPaths = this.modifiedPaths(); + if (modPaths.find(path => optCon.has(path))) { + this.$__.version = dirty.length ? VERSION_ALL : VERSION_WHERE; + } + } else { + this.$__.version = dirty.length ? VERSION_ALL : VERSION_WHERE; + } } if (!dirty.length && VERSION_ALL !== this.$__.version) { diff --git a/test/versioning.test.js b/test/versioning.test.js index 764c1d2a410..cbae5b1e928 100644 --- a/test/versioning.test.js +++ b/test/versioning.test.js @@ -512,6 +512,23 @@ describe('versioning', function() { assert.equal(err.name, 'VersionError'); }); + it('should support optimisticConcurrency being an array of strings', async function() { + const thingSchema = new Schema({ price: Number, name: String }, { optimisticConcurrency: ['price', 'name'] }); + const Thing = db.model('Thing', thingSchema); + + const thing = await Thing.create({ price: 1, name: 'Test' }); + await thing.save(); + assert.equal(thing.__v, 0); + const thing_1 = await Thing.findById(thing.id); + const thing_2 = await Thing.findById(thing.id); + thing_1.set({ price: 2, name: 'Testerson' }); + await thing_1.save(); + assert.equal(thing_1.__v, 1); + thing_2.set({ price: 1, name: 'Test' }); + const err = await thing_2.save().then(() => null, err => err); + assert.ok(!err); + }); + it('gh-1898', async function() { const schema = new Schema({ tags: [String], name: String });