* Commits the currently active transaction in this session. * * @param options - Optional options, can be used to override `defaultTimeoutMS`.
(options?: { timeoutMS?: number })
| 427 | * @param options - Optional options, can be used to override `defaultTimeoutMS`. |
| 428 | */ |
| 429 | async commitTransaction(options?: { timeoutMS?: number }): Promise<void> { |
| 430 | if (this.transaction.state === TxnState.NO_TRANSACTION) { |
| 431 | throw new MongoTransactionError('No transaction started'); |
| 432 | } |
| 433 | |
| 434 | if ( |
| 435 | this.transaction.state === TxnState.STARTING_TRANSACTION || |
| 436 | this.transaction.state === TxnState.TRANSACTION_COMMITTED_EMPTY |
| 437 | ) { |
| 438 | // the transaction was never started, we can safely exit here |
| 439 | this.transaction.transition(TxnState.TRANSACTION_COMMITTED_EMPTY); |
| 440 | return; |
| 441 | } |
| 442 | |
| 443 | if (this.transaction.state === TxnState.TRANSACTION_ABORTED) { |
| 444 | throw new MongoTransactionError( |
| 445 | 'Cannot call commitTransaction after calling abortTransaction' |
| 446 | ); |
| 447 | } |
| 448 | |
| 449 | const command: { |
| 450 | commitTransaction: 1; |
| 451 | writeConcern?: WriteConcernSettings; |
| 452 | recoveryToken?: Document; |
| 453 | maxTimeMS?: number; |
| 454 | } = { commitTransaction: 1 }; |
| 455 | |
| 456 | const timeoutMS = |
| 457 | typeof options?.timeoutMS === 'number' |
| 458 | ? options.timeoutMS |
| 459 | : typeof this.timeoutMS === 'number' |
| 460 | ? this.timeoutMS |
| 461 | : null; |
| 462 | |
| 463 | const wc = this.transaction.options.writeConcern ?? this.clientOptions?.writeConcern; |
| 464 | if (wc != null) { |
| 465 | if (timeoutMS == null && this.timeoutContext == null) { |
| 466 | WriteConcern.apply(command, { wtimeoutMS: 10000, w: 'majority', ...wc }); |
| 467 | } else { |
| 468 | const wcKeys = Object.keys(wc); |
| 469 | if (wcKeys.length > 2 || (!wcKeys.includes('wtimeoutMS') && !wcKeys.includes('wTimeoutMS'))) |
| 470 | // if the write concern was specified with wTimeoutMS, then we set both wtimeoutMS |
| 471 | // and wTimeoutMS, guaranteeing at least two keys, so if we have more than two keys, |
| 472 | // then we can automatically assume that we should add the write concern to the command. |
| 473 | // If it has 2 or fewer keys, we need to check that those keys aren't the wtimeoutMS |
| 474 | // or wTimeoutMS options before we add the write concern to the command |
| 475 | WriteConcern.apply(command, { ...wc, wtimeoutMS: undefined }); |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | if (this.transaction.state === TxnState.TRANSACTION_COMMITTED || this.commitAttempted) { |
| 480 | if (timeoutMS == null && this.timeoutContext == null) { |
| 481 | WriteConcern.apply(command, { wtimeoutMS: 10000, ...wc, w: 'majority' }); |
| 482 | } else { |
| 483 | WriteConcern.apply(command, { w: 'majority', ...wc, wtimeoutMS: undefined }); |
| 484 | } |
| 485 | } |
| 486 |