summaryrefslogtreecommitdiff
path: root/src/mongo/db/session_catalog.cpp
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-09-15 18:03:06 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-09-20 08:55:24 -0400
commitc8cb9cc374af47f862d81e52ad4bc33d96239ef0 (patch)
treebe919dfd6d1a33cfad82b21abc6e3fd2c63b5242 /src/mongo/db/session_catalog.cpp
parentaa3b85fd363e77f7fc1f1c3623422a61d7f70ed7 (diff)
downloadmongo-c8cb9cc374af47f862d81e52ad4bc33d96239ef0.tar.gz
SERVER-31114 Perform targeted session invalidation on direct writes to `config.transactions`
Diffstat (limited to 'src/mongo/db/session_catalog.cpp')
-rw-r--r--src/mongo/db/session_catalog.cpp33
1 files changed, 29 insertions, 4 deletions
diff --git a/src/mongo/db/session_catalog.cpp b/src/mongo/db/session_catalog.cpp
index f155d10639e..8f73410fe1c 100644
--- a/src/mongo/db/session_catalog.cpp
+++ b/src/mongo/db/session_catalog.cpp
@@ -104,7 +104,7 @@ boost::optional<UUID> SessionCatalog::getTransactionTableUUID(OperationContext*
}
void SessionCatalog::onStepUp(OperationContext* opCtx) {
- resetSessions();
+ invalidateSessions(opCtx, boost::none);
DBDirectClient client(opCtx);
@@ -172,10 +172,35 @@ ScopedSession SessionCatalog::getOrCreateSession(OperationContext* opCtx,
return ss;
}
-void SessionCatalog::resetSessions() {
+void SessionCatalog::invalidateSessions(OperationContext* opCtx,
+ boost::optional<BSONObj> singleSessionDoc) {
+ uassert(40528,
+ str::stream() << "Direct writes against "
+ << NamespaceString::kSessionTransactionsTableNamespace.ns()
+ << " cannot be performed using a transaction or on a session.",
+ !opCtx->getLogicalSessionId());
+
+ const auto invalidateSessionFn = [&](WithLock, SessionRuntimeInfoMap::iterator it) {
+ auto& sri = it->second;
+ sri->txnState.invalidate();
+ _txnTable.erase(it);
+ };
+
stdx::lock_guard<stdx::mutex> lg(_mutex);
- for (const auto& it : _txnTable) {
- it.second->txnState.invalidate();
+
+ if (singleSessionDoc) {
+ const auto lsid = LogicalSessionId::parse(IDLParserErrorContext("lsid"),
+ singleSessionDoc->getField("_id").Obj());
+
+ auto it = _txnTable.find(lsid);
+ if (it != _txnTable.end()) {
+ invalidateSessionFn(lg, it);
+ }
+ } else {
+ auto it = _txnTable.begin();
+ while (it != _txnTable.end()) {
+ invalidateSessionFn(lg, it++);
+ }
}
}