A lightweight implementation of the Unit of Work pattern for Mongoose transactions with support for resilient transactions and logging.
npm install mongoose-unit-of-work
import mongoose from "mongoose";
import { UnitOfWork } from "mongoose-unit-of-work";
// Create a unit of work instance
const uow = new UnitOfWork(mongoose.connection);
// Execute a transaction
await uow.executeTransaction(async (session, uow) => {
// Perform your database operations here
const user = await User.create([{ name: "John" }], { session });
const order = await Order.create([{ userId: user[0]._id }], { session });
return { user, order };
});
For handling transient transaction errors with automatic retries:
import { ResilientUnitOfWork } from "mongoose-unit-of-work";
// Create a resilient unit of work instance with custom retry options
const uow = new ResilientUnitOfWork(mongoose.connection, {
maxRetries: 3,
initialDelayMs: 100,
maxDelayMs: 1000,
backoffFactor: 2,
retryableErrors: [
"TransientTransactionError",
"UnknownTransactionCommitResult",
],
});
// Execute a transaction with automatic retries
await uow.executeTransaction(async (session, uow) => {
// Your transaction code here
});
- Simple transaction management
- Automatic session handling
- Error handling with automatic rollback
- TypeScript support
- Built-in logging support
- Resilient transactions with configurable retry options
- Configurable transaction options (read concern, write concern, read preference)
- begin(): Start a new transaction
- commit(): Commit the current transaction
- abort(): Rollback the current transaction
- dispose(): Clean up resources
- executeTransaction<T>(fn): Execute a function within a transaction
- getSession(): Get the current session
- execute<T>(fn): Execute a function within an existing transaction
Extends UnitOfWork with additional features:
- Automatic retry on transient transaction errors
- Configurable retry options
- Exponential backoff strategy
const DEFAULT_SESSION_OPTIONS = {
readConcern: "snapshot",
writeConcern: {
w: "majority",
wtimeout: 3000,
},
readPreference: "primary",
};
const DEFAULT_RETRY_OPTIONS = {
maxRetries: 3,
initialDelayMs: 100,
maxDelayMs: 1000,
backoffFactor: 2,
retryableErrors: [
"TransientTransactionError",
"UnknownTransactionCommitResult",
],
};
- Node.js >= 14
- Mongoose >= 8.15.2
MIT