@tmlmobilidade/interfaces
Version:
This package provides SDK-style connectors for interacting with databases (e.g., stops, plans, rides, alerts) and external providers (e.g., authentication, storage). It simplifies data access and integration across projects.
62 lines (61 loc) • 1.99 kB
JavaScript
/**
* NOTE: TRANSACTIONS ARE ONLY SUPPORTED BY REPLICA SETS
*
* Transaction numbers are only allowed on a replica set member or mongos
*
* @see https://www.mongodb.com/docs/manual/core/transactions-operations/
*/
export class Transaction {
mongoConnector;
session;
constructor(mongoConnector) {
this.mongoConnector = mongoConnector;
}
async abort() {
await this.session.abortTransaction();
await this.session.endSession();
}
async commit() {
await this.session.commitTransaction();
await this.session.endSession();
}
getSession() {
return this.session;
}
async start() {
this.session = (await this.mongoConnector).client.startSession();
this.session.startTransaction();
}
}
export class TransactionManager {
collections;
transactions = new Map();
constructor(collections) {
this.collections = collections;
}
async withTransaction(callback) {
try {
// Start transactions for each collection
for (const collection of this.collections) {
const transaction = new Transaction(collection.getMongoConnector());
await transaction.start();
this.transactions.set(collection, transaction);
}
// Execute callback with collections and transaction map
const result = await callback(this.collections, this.transactions);
// If successful, commit all transactions
await Promise.all(Array.from(this.transactions.values()).map(transaction => transaction.commit()));
return result;
}
catch (error) {
// If any error occurs, abort all transactions
for (const transaction of this.transactions.values()) {
await transaction.abort();
}
throw error;
}
finally {
this.transactions.clear();
}
}
}