summaryrefslogtreecommitdiff
path: root/src/mongo/db/session.h
diff options
context:
space:
mode:
authorJudah Schvimer <judah@mongodb.com>2018-07-20 13:11:12 -0400
committerJudah Schvimer <judah@mongodb.com>2018-07-20 13:17:19 -0400
commit5b6fbcf0dc4065d725b23c6fd3911a24e078e34d (patch)
treef5da305a6d3dfb072146fa75f592c67099a03bd9 /src/mongo/db/session.h
parent4cdaee88d7122f3ccba152ae37d3b5b69b3b398f (diff)
downloadmongo-5b6fbcf0dc4065d725b23c6fd3911a24e078e34d.tar.gz
SERVER-35597 SERVER-35598 Ensure prepared transactions can be committed
Diffstat (limited to 'src/mongo/db/session.h')
-rw-r--r--src/mongo/db/session.h35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/mongo/db/session.h b/src/mongo/db/session.h
index f4e81465137..c9546269b83 100644
--- a/src/mongo/db/session.h
+++ b/src/mongo/db/session.h
@@ -274,8 +274,11 @@ public:
/**
* Commits the transaction, including committing the write unit of work and updating
* transaction state.
+ *
+ * If the transaction is prepared, a 'commitTimestamp' is expected, otherwise providing one will
+ * throw an exception.
*/
- void commitTransaction(OperationContext* opCtx);
+ void commitTransaction(OperationContext* opCtx, boost::optional<Timestamp> commitTimestamp);
/**
* Puts a transaction into a prepared state.
@@ -399,7 +402,7 @@ public:
void transitionToCommittingforTest() {
stdx::lock_guard<stdx::mutex> lk(_mutex);
- _txnState.transitionTo(lk, TransitionTable::State::kCommitting);
+ _txnState.transitionTo(lk, TransitionTable::State::kCommittingWithoutPrepare);
}
private:
@@ -453,7 +456,15 @@ private:
*/
class TransitionTable {
public:
- enum class State { kNone, kInProgress, kPrepared, kCommitting, kCommitted, kAborted };
+ enum class State {
+ kNone,
+ kInProgress,
+ kPrepared,
+ kCommittingWithoutPrepare,
+ kCommittingWithPrepare,
+ kCommitted,
+ kAborted
+ };
/**
* Transitions the session from the current state to the new state. If transition validation
@@ -481,8 +492,12 @@ private:
return _state == State::kPrepared;
}
- bool isCommitting(WithLock) const {
- return _state == State::kCommitting;
+ bool isCommittingWithoutPrepare(WithLock) const {
+ return _state == State::kCommittingWithoutPrepare;
+ }
+
+ bool isCommittingWithPrepare(WithLock) const {
+ return _state == State::kCommittingWithPrepare;
}
bool isCommitted(WithLock) const {
@@ -518,11 +533,11 @@ private:
// Releases stashed transaction resources to abort the transaction.
void _abortTransaction(WithLock);
- // Committing a transaction first changes its state to "Committing" and writes to the oplog,
+ // Committing a transaction first changes its state to "Committing*" and writes to the oplog,
// then it changes the state to "Committed".
//
- // When a transaction is in "Committing" state, it's not allowed for other threads to change its
- // state (i.e. abort the transaction), otherwise the on-disk state will diverge from the
+ // When a transaction is in "Committing*" state, it's not allowed for other threads to change
+ // its state (i.e. abort the transaction), otherwise the on-disk state will diverge from the
// in-memory state.
// There are 3 cases where the transaction will be aborted.
// 1) abortTransaction command. Session check-out mechanism only allows one client to access a
@@ -530,7 +545,9 @@ private:
// 2) killSession, stepdown, transaction timeout and any thread that aborts the transaction
// outside of session checkout. They can safely skip the committing transactions.
// 3) Migration. Should be able to skip committing transactions.
- void _commitTransaction(stdx::unique_lock<stdx::mutex> lk, OperationContext* opCtx);
+ void _commitTransaction(stdx::unique_lock<stdx::mutex> lk,
+ OperationContext* opCtx,
+ boost::optional<Timestamp> commitTimestamp);
const LogicalSessionId _sessionId;