summaryrefslogtreecommitdiff
path: root/src/mongo/db/db_raii.h
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2017-03-02 13:54:24 -0500
committerCharlie Swanson <charlie.swanson@mongodb.com>2017-03-15 11:03:44 -0400
commitf05b9437fbdc53deecf55ed3c20e36af3d733953 (patch)
tree8b66acc133f83f27ef00f31600538f225ec2746a /src/mongo/db/db_raii.h
parenta1f15dfd788a78da77bda6675132d4144691fce1 (diff)
downloadmongo-f05b9437fbdc53deecf55ed3c20e36af3d733953.tar.gz
SERVER-22541 Refactor RAII locking helpers.
Removes the class 'ScopedTransaction' and moves the responsibility of abandoning the snapshot onto the GlobalLock class. Also renames the AutoGetCollectionForRead class to AutoGetCollectionForReadCommand, and adds a new AutoGetCollectionForRead class. Unlike AutoGetCollectionForReadCommand, this new class will not update the namespace on the CurrentOp object, nor will it add an entry to Top.
Diffstat (limited to 'src/mongo/db/db_raii.h')
-rw-r--r--src/mongo/db/db_raii.h107
1 files changed, 87 insertions, 20 deletions
diff --git a/src/mongo/db/db_raii.h b/src/mongo/db/db_raii.h
index 04d1658b24d..8060d06f000 100644
--- a/src/mongo/db/db_raii.h
+++ b/src/mongo/db/db_raii.h
@@ -46,6 +46,9 @@ class Collection;
* RAII-style class, which acquires a lock on the specified database in the requested mode and
* obtains a reference to the database. Used as a shortcut for calls to dbHolder().get().
*
+ * Use this when you want to do a database-level operation, like read a list of all collections, or
+ * drop a collection.
+ *
* It is guaranteed that the lock will be released when this object goes out of scope, therefore
* the database reference returned by this class should not be retained.
*/
@@ -68,6 +71,10 @@ private:
* RAII-style class, which acquires a locks on the specified database and collection in the
* requested mode and obtains references to both.
*
+ * Use this when you want to access something at the collection level, but do not want to do any of
+ * the tasks associated with the 'ForRead' variants below. For example, you can use this to access a
+ * Collection's CursorManager, or to remove a document.
+ *
* It is guaranteed that locks will be released when this object goes out of scope, therefore
* the database and the collection references returned by this class should not be retained.
*/
@@ -87,10 +94,10 @@ public:
: AutoGetCollection(opCtx, nss, modeDB, modeColl, ViewMode::kViewsForbidden) {}
/**
- * This constructor is inteded for internal use and should not be used outside this file.
- * AutoGetCollectionForRead and AutoGetCollectionOrViewForRead use ViewMode to determine whether
- * or not it is permissible to obtain a handle on a view namespace. Use another constructor or
- * another AutoGet class instead.
+ * This constructor is intended for internal use and should not be used outside this file.
+ * AutoGetCollectionForReadCommand and AutoGetCollectionOrViewForReadCommand use 'viewMode' to
+ * determine whether or not it is permissible to obtain a handle on a view namespace. Use
+ * another constructor or another 'AutoGet' class instead.
*/
AutoGetCollection(OperationContext* opCtx,
const NamespaceString& nss,
@@ -98,10 +105,16 @@ public:
LockMode modeColl,
ViewMode viewMode);
+ /**
+ * Returns nullptr if the database didn't exist.
+ */
Database* getDb() const {
return _autoDb.getDb();
}
+ /**
+ * Returns nullptr if the collection didn't exist.
+ */
Collection* getCollection() const {
return _coll;
}
@@ -115,7 +128,8 @@ private:
Collection* const _coll;
friend class AutoGetCollectionForRead;
- friend class AutoGetCollectionOrViewForRead;
+ friend class AutoGetCollectionForReadCommand;
+ friend class AutoGetCollectionOrViewForReadCommand;
};
/**
@@ -125,6 +139,9 @@ private:
* MODE_IX or MODE_X. If the database needs to be created, the lock will automatically be
* reacquired as MODE_X.
*
+ * Use this when you are about to perform a write, and want to create the database if it doesn't
+ * already exist.
+ *
* It is guaranteed that locks will be released when this object goes out of scope, therefore
* the database reference returned by this class should not be retained.
*/
@@ -147,17 +164,20 @@ public:
}
private:
- ScopedTransaction _transaction;
Lock::DBLock _dbLock; // not const, as we may need to relock for implicit create
Database* _db;
bool _justCreated;
};
/**
- * RAII-style class, which would acquire the appropritate hierarchy of locks for obtaining
+ * RAII-style class, which would acquire the appropriate hierarchy of locks for obtaining
* a particular collection and would retrieve a reference to the collection. In addition, this
- * utility validates the shard version for the specified namespace and sets the current operation's
- * namespace for the duration while this object is alive.
+ * utility will ensure that the read will be performed against an appropriately committed snapshot
+ * if the operation is using a readConcern of 'majority'.
+ *
+ * Use this when you want to read the contents of a collection, but you are not at the top-level of
+ * some command. This will ensure your reads obey any requested readConcern, but will not update the
+ * status of CurrentOp, or add a Top entry.
*
* It is guaranteed that locks will be released when this object goes out of scope, therefore
* database and collection references returned by this class should not be retained.
@@ -169,7 +189,15 @@ public:
AutoGetCollectionForRead(OperationContext* opCtx, const NamespaceString& nss)
: AutoGetCollectionForRead(opCtx, nss, AutoGetCollection::ViewMode::kViewsForbidden) {}
- ~AutoGetCollectionForRead();
+ /**
+ * This constructor is intended for internal use and should not be used outside this file.
+ * AutoGetCollectionForReadCommand and AutoGetCollectionOrViewForReadCommand use 'viewMode' to
+ * determine whether or not it is permissible to obtain a handle on a view namespace. Use
+ * another constructor or another 'AutoGet' class instead.
+ */
+ AutoGetCollectionForRead(OperationContext* opCtx,
+ const NamespaceString& nss,
+ AutoGetCollection::ViewMode viewMode);
Database* getDb() const {
return _autoColl->getDb();
@@ -180,34 +208,73 @@ public:
}
private:
- void _ensureMajorityCommittedSnapshotIsValid(const NamespaceString& nss);
+ void _ensureMajorityCommittedSnapshotIsValid(const NamespaceString& nss,
+ OperationContext* opCtx);
- const Timer _timer;
+ boost::optional<AutoGetCollection> _autoColl;
+};
+
+/**
+ * RAII-style class, which would acquire the appropriate hierarchy of locks for obtaining
+ * a particular collection and would retrieve a reference to the collection. In addition, this
+ * utility validates the shard version for the specified namespace and sets the current operation's
+ * namespace for the duration while this object is alive.
+ *
+ * Use this when you are a read-only command and you know that your target namespace is a collection
+ * (not a view). In addition to ensuring your read obeys any requested readConcern, this will add a
+ * Top entry upon destruction and ensure the CurrentOp object has the right namespace and has
+ * started its timer.
+ *
+ * It is guaranteed that locks will be released when this object goes out of scope, therefore
+ * database and collection references returned by this class should not be retained.
+ */
+class AutoGetCollectionForReadCommand {
+ MONGO_DISALLOW_COPYING(AutoGetCollectionForReadCommand);
+
+public:
+ AutoGetCollectionForReadCommand(OperationContext* opCtx, const NamespaceString& nss)
+ : AutoGetCollectionForReadCommand(
+ opCtx, nss, AutoGetCollection::ViewMode::kViewsForbidden) {}
+
+ ~AutoGetCollectionForReadCommand();
+
+ Database* getDb() const {
+ return _autoCollForRead->getDb();
+ }
+
+ Collection* getCollection() const {
+ return _autoCollForRead->getCollection();
+ }
+
+private:
OperationContext* const _opCtx;
- const ScopedTransaction _transaction;
+ const Timer _timer;
protected:
- AutoGetCollectionForRead(OperationContext* opCtx,
- const NamespaceString& nss,
- AutoGetCollection::ViewMode viewMode);
+ AutoGetCollectionForReadCommand(OperationContext* opCtx,
+ const NamespaceString& nss,
+ AutoGetCollection::ViewMode viewMode);
/**
* This protected section must come after the private section because
* AutoGetCollectionOrViewForRead needs access to _autoColl, but _autoColl must be initialized
* after _transaction.
*/
- boost::optional<AutoGetCollection> _autoColl;
+ boost::optional<AutoGetCollectionForRead> _autoCollForRead;
};
/**
* RAII-style class for obtaining a collection or view for reading. The pointer to a view definition
* is nullptr if it does not exist.
+ *
+ * Use this when you are a read-only command, but have not yet determined if the namespace is a view
+ * or a collection.
*/
-class AutoGetCollectionOrViewForRead final : public AutoGetCollectionForRead {
- MONGO_DISALLOW_COPYING(AutoGetCollectionOrViewForRead);
+class AutoGetCollectionOrViewForReadCommand final : public AutoGetCollectionForReadCommand {
+ MONGO_DISALLOW_COPYING(AutoGetCollectionOrViewForReadCommand);
public:
- AutoGetCollectionOrViewForRead(OperationContext* opCtx, const NamespaceString& nss);
+ AutoGetCollectionOrViewForReadCommand(OperationContext* opCtx, const NamespaceString& nss);
ViewDefinition* getView() const {
return _view.get();