Skip to content

Commit 4aeaedf

Browse files
author
Thomas Reggi
authored
fix: handle session with unacknowledged write
If there's an explicit session and the writeConcern is `unacknowledged` an error will now be thrown. If there's an implicit session and the writeConcern is `unacknowledged` the session will not be sent to the server. NODE-1341
1 parent bb13764 commit 4aeaedf

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

src/sessions.ts

+8
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,14 @@ function applySession(session: any, command: any, options?: any): MongoError | u
716716
return new MongoError('Cannot use a session that has ended');
717717
}
718718

719+
// SPEC-1019: silently ignore explicit session with unacknowledged write for backwards compatibility
720+
if (options && options.writeConcern && options.writeConcern.w === 0) {
721+
if (session && session.explicit) {
722+
return new MongoError('Cannot have explicit session with unacknowledged writes');
723+
}
724+
return;
725+
}
726+
719727
// mark the last use of this session, and apply the `lsid`
720728
serverSession.lastUse = now();
721729
command.lsid = serverSession.id;

test/functional/sessions.test.js

+44-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
2+
23
const expect = require('chai').expect;
34
const setupDatabase = require('./shared').setupDatabase;
5+
const withMonitoredClient = require('./shared').withMonitoredClient;
46
const TestRunnerContext = require('./spec-runner').TestRunnerContext;
57
const generateTopologyTests = require('./spec-runner').generateTopologyTests;
68
const loadSpecTests = require('../spec').loadSpecTests;
@@ -43,7 +45,7 @@ describe('Sessions', function () {
4345

4446
it('should send endSessions for multiple sessions', {
4547
metadata: {
46-
requires: { topology: ['single'], mongodb: '>3.6.0' },
48+
requires: { topology: ['single'], mongodb: '>=3.6.0' },
4749
// Skipping session leak tests b/c these are explicit sessions
4850
sessions: { skipLeakTests: true }
4951
},
@@ -65,7 +67,7 @@ describe('Sessions', function () {
6567
});
6668

6769
describe('withSession', {
68-
metadata: { requires: { mongodb: '>3.6.0' } },
70+
metadata: { requires: { mongodb: '>=3.6.0' } },
6971
test: function () {
7072
beforeEach(function () {
7173
return test.setup(this.configuration);
@@ -194,4 +196,44 @@ describe('Sessions', function () {
194196

195197
generateTopologyTests(testSuites, testContext, testFilter);
196198
});
199+
200+
context('unacknowledged writes', () => {
201+
it('should not include session for unacknowledged writes', {
202+
metadata: { requires: { topology: 'single', mongodb: '>=3.6.0' } },
203+
test: withMonitoredClient('insert', { clientOptions: { w: 0 } }, function (
204+
client,
205+
events,
206+
done
207+
) {
208+
client
209+
.db('test')
210+
.collection('foo')
211+
.insertOne({ foo: 'bar' }, err => {
212+
expect(err).to.not.exist;
213+
const event = events[0];
214+
expect(event).nested.property('command.writeConcern.w').to.equal(0);
215+
expect(event).to.not.have.nested.property('command.lsid');
216+
done();
217+
});
218+
})
219+
});
220+
it('should throw error with explicit session', {
221+
metadata: { requires: { topology: 'replicaset', mongodb: '>=3.6.0' } },
222+
test: withMonitoredClient('insert', { clientOptions: { w: 0 } }, function (
223+
client,
224+
events,
225+
done
226+
) {
227+
const session = client.startSession({ causalConsistency: true });
228+
client
229+
.db('test')
230+
.collection('foo')
231+
.insertOne({ foo: 'bar' }, { session }, err => {
232+
expect(err).to.exist;
233+
expect(err.message).to.equal('Cannot have explicit session with unacknowledged writes');
234+
client.close(done);
235+
});
236+
})
237+
});
238+
});
197239
});

0 commit comments

Comments
 (0)