summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Schultz <william.schultz@mongodb.com>2018-07-23 12:20:11 -0400
committerWilliam Schultz <william.schultz@mongodb.com>2018-07-23 12:20:11 -0400
commit826d21952137b50e6376cea627995d24a9eb54a9 (patch)
treeb3decb90d9cfa30078293b7021c83c9122749785
parenta73722cc85bd1027898be8af651e1312d68a680b (diff)
downloadmongo-826d21952137b50e6376cea627995d24a9eb54a9.tar.gz
SERVER-35695 Add server parameter to enable transactions on inMemory
storage engine
-rw-r--r--jstests/noPassthrough/transactions_enabled_in_memory_parameter.js53
-rw-r--r--src/mongo/db/initialize_operation_session_info.cpp17
2 files changed, 69 insertions, 1 deletions
diff --git a/jstests/noPassthrough/transactions_enabled_in_memory_parameter.js b/jstests/noPassthrough/transactions_enabled_in_memory_parameter.js
new file mode 100644
index 00000000000..870bc4a3748
--- /dev/null
+++ b/jstests/noPassthrough/transactions_enabled_in_memory_parameter.js
@@ -0,0 +1,53 @@
+/**
+ * Verify that transactions can be run on the in-memory storage engine with the
+ * 'enableInMemoryTransactions' parameter.
+ */
+(function() {
+ "use strict";
+
+ if (jsTest.options().storageEngine !== "inMemory") {
+ jsTestLog("Skipping test because storageEngine is not inMemory");
+ return;
+ }
+
+ const dbName = "test";
+ const collName = "transactions_enabled_in_memory_parameter";
+
+ const replTest = new ReplSetTest({name: collName, nodes: 1});
+ replTest.startSet({storageEngine: "inMemory"});
+ replTest.initiate();
+
+ const primary = replTest.getPrimary();
+
+ // Initiate a session.
+ const sessionOptions = {causalConsistency: false};
+ const session = primary.getDB(dbName).getMongo().startSession(sessionOptions);
+ const sessionDb = session.getDatabase(dbName);
+
+ // Create collection.
+ assert.commandWorked(sessionDb[collName].insert({x: 0}));
+
+ // Check the default parameter value.
+ let res = primary.adminCommand({"getParameter": 1, "enableInMemoryTransactions": 1});
+ assert.eq(res.enableInMemoryTransactions, false);
+
+ // Try to start a transaction that should fail.
+ session.startTransaction();
+ assert.commandFailedWithCode(sessionDb[collName].insert({x: 1}), ErrorCodes.IllegalOperation);
+ // The abort command will fail on the server, but should reset the local transaction state
+ // appropriately.
+ assert.commandFailedWithCode(session.abortTransaction_forTesting(),
+ ErrorCodes.IllegalOperation);
+
+ // Enable in-memory transactions.
+ assert.commandWorked(
+ primary.adminCommand({"setParameter": 1, "enableInMemoryTransactions": true}));
+
+ // Start a transaction that should succeed.
+ session.startTransaction();
+ assert.commandWorked(sessionDb[collName].insert({x: 2}));
+ session.commitTransaction();
+
+ session.endSession();
+ replTest.stopSet();
+}());
diff --git a/src/mongo/db/initialize_operation_session_info.cpp b/src/mongo/db/initialize_operation_session_info.cpp
index 965dc0f1e53..446170d63f2 100644
--- a/src/mongo/db/initialize_operation_session_info.cpp
+++ b/src/mongo/db/initialize_operation_session_info.cpp
@@ -34,9 +34,16 @@
#include "mongo/db/logical_session_cache.h"
#include "mongo/db/logical_session_id_helpers.h"
#include "mongo/db/operation_context.h"
+#include "mongo/db/server_parameters.h"
namespace mongo {
+// Allows multi-document transactions to run with the 'inMemory' storage engine. This flag should
+// ONLY be used for testing purposes. Production systems should not run transactions on the
+// 'inMemory' storage engines until "rollback to a timestamp" is supported on the 'inMemory' storage
+// engine (see SERVER-34165).
+MONGO_EXPORT_SERVER_PARAMETER(enableInMemoryTransactions, bool, false);
+
boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo(
OperationContext* opCtx,
const BSONObj& requestBody,
@@ -107,10 +114,18 @@ boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo(
uassert(ErrorCodes::InvalidOptions,
"Specifying autocommit=true is not allowed.",
!osi.getAutocommit().value());
+
+ // We allow transactions to run on in-memory storage engines for testing purposes.
+ bool allowInMemoryTransactions = false;
+ auto storageEngine = opCtx->getServiceContext()->getStorageEngine();
+ if (storageEngine) {
+ allowInMemoryTransactions =
+ storageEngine->isEphemeral() && enableInMemoryTransactions.load();
+ }
uassert(ErrorCodes::IllegalOperation,
"Multi-document transactions are only allowed on storage engines that support "
"recover to stable timestamp.",
- supportsRecoverToStableTimestamp);
+ supportsRecoverToStableTimestamp || allowInMemoryTransactions);
} else {
uassert(ErrorCodes::InvalidOptions,
"'startTransaction' field requires 'autocommit' field to also be specified",