transactions.js
5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isTransactionCommand = exports.Transaction = exports.TxnState = void 0;
const error_1 = require("./error");
const read_concern_1 = require("./read_concern");
const read_preference_1 = require("./read_preference");
const write_concern_1 = require("./write_concern");
/** @internal */
exports.TxnState = Object.freeze({
NO_TRANSACTION: 'NO_TRANSACTION',
STARTING_TRANSACTION: 'STARTING_TRANSACTION',
TRANSACTION_IN_PROGRESS: 'TRANSACTION_IN_PROGRESS',
TRANSACTION_COMMITTED: 'TRANSACTION_COMMITTED',
TRANSACTION_COMMITTED_EMPTY: 'TRANSACTION_COMMITTED_EMPTY',
TRANSACTION_ABORTED: 'TRANSACTION_ABORTED'
});
const stateMachine = {
[exports.TxnState.NO_TRANSACTION]: [exports.TxnState.NO_TRANSACTION, exports.TxnState.STARTING_TRANSACTION],
[exports.TxnState.STARTING_TRANSACTION]: [
exports.TxnState.TRANSACTION_IN_PROGRESS,
exports.TxnState.TRANSACTION_COMMITTED,
exports.TxnState.TRANSACTION_COMMITTED_EMPTY,
exports.TxnState.TRANSACTION_ABORTED
],
[exports.TxnState.TRANSACTION_IN_PROGRESS]: [
exports.TxnState.TRANSACTION_IN_PROGRESS,
exports.TxnState.TRANSACTION_COMMITTED,
exports.TxnState.TRANSACTION_ABORTED
],
[exports.TxnState.TRANSACTION_COMMITTED]: [
exports.TxnState.TRANSACTION_COMMITTED,
exports.TxnState.TRANSACTION_COMMITTED_EMPTY,
exports.TxnState.STARTING_TRANSACTION,
exports.TxnState.NO_TRANSACTION
],
[exports.TxnState.TRANSACTION_ABORTED]: [exports.TxnState.STARTING_TRANSACTION, exports.TxnState.NO_TRANSACTION],
[exports.TxnState.TRANSACTION_COMMITTED_EMPTY]: [
exports.TxnState.TRANSACTION_COMMITTED_EMPTY,
exports.TxnState.NO_TRANSACTION
]
};
const ACTIVE_STATES = new Set([
exports.TxnState.STARTING_TRANSACTION,
exports.TxnState.TRANSACTION_IN_PROGRESS
]);
const COMMITTED_STATES = new Set([
exports.TxnState.TRANSACTION_COMMITTED,
exports.TxnState.TRANSACTION_COMMITTED_EMPTY,
exports.TxnState.TRANSACTION_ABORTED
]);
/**
* @public
* A class maintaining state related to a server transaction. Internal Only
*/
class Transaction {
/** Create a transaction @internal */
constructor(options) {
options = options !== null && options !== void 0 ? options : {};
this.state = exports.TxnState.NO_TRANSACTION;
this.options = {};
const writeConcern = write_concern_1.WriteConcern.fromOptions(options);
if (writeConcern) {
if (writeConcern.w === 0) {
throw new error_1.MongoTransactionError('Transactions do not support unacknowledged write concern');
}
this.options.writeConcern = writeConcern;
}
if (options.readConcern) {
this.options.readConcern = read_concern_1.ReadConcern.fromOptions(options);
}
if (options.readPreference) {
this.options.readPreference = read_preference_1.ReadPreference.fromOptions(options);
}
if (options.maxCommitTimeMS) {
this.options.maxTimeMS = options.maxCommitTimeMS;
}
// TODO: This isn't technically necessary
this._pinnedServer = undefined;
this._recoveryToken = undefined;
}
/** @internal */
get server() {
return this._pinnedServer;
}
get recoveryToken() {
return this._recoveryToken;
}
get isPinned() {
return !!this.server;
}
/** @returns Whether the transaction has started */
get isStarting() {
return this.state === exports.TxnState.STARTING_TRANSACTION;
}
/**
* @returns Whether this session is presently in a transaction
*/
get isActive() {
return ACTIVE_STATES.has(this.state);
}
get isCommitted() {
return COMMITTED_STATES.has(this.state);
}
/**
* Transition the transaction in the state machine
* @internal
* @param nextState - The new state to transition to
*/
transition(nextState) {
const nextStates = stateMachine[this.state];
if (nextStates && nextStates.includes(nextState)) {
this.state = nextState;
if (this.state === exports.TxnState.NO_TRANSACTION ||
this.state === exports.TxnState.STARTING_TRANSACTION ||
this.state === exports.TxnState.TRANSACTION_ABORTED) {
this.unpinServer();
}
return;
}
throw new error_1.MongoRuntimeError(`Attempted illegal state transition from [${this.state}] to [${nextState}]`);
}
/** @internal */
pinServer(server) {
if (this.isActive) {
this._pinnedServer = server;
}
}
/** @internal */
unpinServer() {
this._pinnedServer = undefined;
}
}
exports.Transaction = Transaction;
function isTransactionCommand(command) {
return !!(command.commitTransaction || command.abortTransaction);
}
exports.isTransactionCommand = isTransactionCommand;
//# sourceMappingURL=transactions.js.map