@myfunc/prisma-transactional
Version:
Decorator that wraps all prisma queries along the whole call stack to a single transaction.
57 lines (55 loc) • 2.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrismaTransactional = exports.ClsServiceManager = exports.ClsService = void 0;
const nestjs_cls_1 = require("nestjs-cls");
Object.defineProperty(exports, "ClsService", { enumerable: true, get: function () { return nestjs_cls_1.ClsService; } });
Object.defineProperty(exports, "ClsServiceManager", { enumerable: true, get: function () { return nestjs_cls_1.ClsServiceManager; } });
const const_1 = require("./const");
const manager_1 = require("./manager");
/** That solution can creates and merge transactions.
BE CAREFUL when using it, all queries inside transaction will be isolated and can lead to deadlock.
Found here https://github.com/prisma/prisma/issues/5729
*/
function PrismaTransactional(isolationLevel) {
return (target, propertyKey, descriptor) => {
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
return PrismaTransactional.execute(() => originalMethod.apply(this, [...args]), isolationLevel);
};
};
}
exports.PrismaTransactional = PrismaTransactional;
// Utility to manage success callback queue
PrismaTransactional.onSuccess = (callback) => {
const clsService = nestjs_cls_1.ClsServiceManager.getClsService();
const isActiveTransaction = clsService.get(const_1.TX_CLIENT_KEY);
if (isActiveTransaction) {
const existingCallbacks = clsService.get(const_1.TX_CLIENT_SUCCESS_CALLBACKS) || [];
clsService.set(const_1.TX_CLIENT_SUCCESS_CALLBACKS, [...existingCallbacks, callback]);
}
else {
return callback();
}
};
// Run callback in transaction
PrismaTransactional.execute = (callback, isolationLevel) => {
const cls = nestjs_cls_1.ClsServiceManager.getClsService();
if (cls.get(const_1.TX_CLIENT_KEY)) {
return callback();
}
else {
return manager_1.Manager.prismaClient['$root'].$transaction(async () => {
return callback();
}, {
isolationLevel,
timeout: const_1.TRANSACTION_TIMEOUT,
});
}
};
PrismaTransactional.prismaRoot = null;
// Run query with no transaction even if it exists.
Object.defineProperty(PrismaTransactional, 'prismaRoot', {
get() {
return manager_1.Manager.prismaClient['$root'];
},
});