Files
bigcapital/packages/server/src/services/UnitOfWork/index.ts
2024-03-13 02:14:25 +02:00

66 lines
1.6 KiB
TypeScript

import { Service, Inject } from 'typedi';
import TenancyService from '@/services/Tenancy/TenancyService';
import { Transaction } from 'objection';
/**
* Enumeration that represents transaction isolation levels for use with the {@link Transactional} annotation
*/
export enum IsolationLevel {
/**
* A constant indicating that dirty reads, non-repeatable reads and phantom reads can occur.
*/
READ_UNCOMMITTED = 'read uncommitted',
/**
* A constant indicating that dirty reads are prevented; non-repeatable reads and phantom reads can occur.
*/
READ_COMMITTED = 'read committed',
/**
* A constant indicating that dirty reads and non-repeatable reads are prevented; phantom reads can occur.
*/
REPEATABLE_READ = 'repeatable read',
/**
* A constant indicating that dirty reads, non-repeatable reads and phantom reads are prevented.
*/
SERIALIZABLE = 'serializable',
}
@Service()
export default class UnitOfWork {
@Inject()
tenancy: TenancyService;
/**
*
* @param {number} tenantId
* @param {} work
* @param {IsolationLevel} isolationLevel
* @returns {}
*/
public withTransaction = async (
tenantId: number,
work,
trx?: Transaction,
isolationLevel: IsolationLevel = IsolationLevel.READ_UNCOMMITTED
) => {
const knex = this.tenancy.knex(tenantId);
let _trx = trx;
if (!_trx) {
_trx = await knex.transaction({ isolationLevel });
}
try {
const result = await work(_trx);
if (!trx) {
_trx.commit();
}
return result;
} catch (error) {
if (!trx) {
_trx.rollback();
}
throw error;
}
};
}