From 84da063a67fee56e7e088891dc170fd8dee4147e Mon Sep 17 00:00:00 2001 From: Siyuan Zhou Date: Thu, 22 Feb 2018 17:46:42 -0500 Subject: SERVER-33477 Always use upsert with _id for session update. Transactions stash the writes so the in-memory state of transaction table is out of sync during transaction. Two threads (write and chunk migration) will not update the same session entry due to the WCE generated by storage engine. --- jstests/noPassthrough/readConcern_snapshot.js | 11 +++++------ src/mongo/db/session.cpp | 14 ++------------ 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/jstests/noPassthrough/readConcern_snapshot.js b/jstests/noPassthrough/readConcern_snapshot.js index 526a5c17b37..e67cf525736 100644 --- a/jstests/noPassthrough/readConcern_snapshot.js +++ b/jstests/noPassthrough/readConcern_snapshot.js @@ -193,17 +193,16 @@ }))); assert.eq({_id: 0, a: 1}, sessionDb.coll.findOne({_id: 0})); - // readConcern 'snapshot' is not yet supported by multi-statement updates. + // readConcern 'snapshot' is supported by multi-statement updates. assert.commandWorked(sessionDb.coll.insert({_id: 1}, {writeConcern: {w: "majority"}})); - assert.commandFailedWithCode(sessionDb.runCommand({ + assert.commandWorked(sessionDb.runCommand({ update: collName, updates: [{q: {_id: 0}, u: {$inc: {a: 1}}}, {q: {_id: 1}, u: {$inc: {a: 1}}}], readConcern: {level: "snapshot"}, txnNumber: NumberLong(txnNumber++) - }), - ErrorCodes.WriteConflict); - assert.eq({_id: 0, a: 1}, sessionDb.coll.findOne({_id: 0})); - assert.eq({_id: 1}, sessionDb.coll.findOne({_id: 1})); + })); + assert.eq({_id: 0, a: 2}, sessionDb.coll.findOne({_id: 0})); + assert.eq({_id: 1, a: 1}, sessionDb.coll.findOne({_id: 1})); // readConcern 'snapshot' is not supported by delete. // TODO SERVER-33354: Add snapshot support for delete. diff --git a/src/mongo/db/session.cpp b/src/mongo/db/session.cpp index 8b358ed1901..f1773c3a682 100644 --- a/src/mongo/db/session.cpp +++ b/src/mongo/db/session.cpp @@ -600,18 +600,8 @@ UpdateRequest Session::_makeUpdateRequest(WithLock, return newTxnRecord.toBSON(); }(); updateRequest.setUpdates(updateBSON); - - if (_lastWrittenSessionRecord) { - updateRequest.setQuery(BSON(SessionTxnRecord::kSessionIdFieldName - << _sessionId.toBSON() - << SessionTxnRecord::kTxnNumFieldName - << _lastWrittenSessionRecord->getTxnNum() - << SessionTxnRecord::kLastWriteOpTimeFieldName - << _lastWrittenSessionRecord->getLastWriteOpTime())); - } else { - updateRequest.setQuery(updateBSON); - updateRequest.setUpsert(true); - } + updateRequest.setQuery(BSON(SessionTxnRecord::kSessionIdFieldName << _sessionId.toBSON())); + updateRequest.setUpsert(true); return updateRequest; } -- cgit v1.2.1