UNPKG

@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
"use strict"; 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']; }, });