transactions.js 5.4 KB

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