You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					138 lines
				
				5.0 KiB
			
		
		
			
		
	
	
					138 lines
				
				5.0 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"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 ?? {};
							 | 
						||
| 
								 | 
							
								        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
							 |