UNPKG

inceptum

Version:

hipages take on the foundational library for enterprise-grade apps written in NodeJS

133 lines 4.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DBTransaction = void 0; const prom_client_1 = require("prom-client"); const TransactionManager_1 = require("../transaction/TransactionManager"); const LogManager_1 = require("../log/LogManager"); const LOGGER = LogManager_1.LogManager.getLogger(__filename); const transactionExecutionDurationsHistogram = new prom_client_1.Histogram({ name: 'db_transaction_execute_time', help: 'Time required to execute a transaction', labelNames: ['clientName', 'readonly'], buckets: [0.003, 0.005, 0.01, 0.05, 0.1, 0.3, 1, 5], }); const rolledBackTransactionsCounter = new prom_client_1.Counter({ name: 'db_transaction_rollback_counter', help: 'Number of times transactions have been rolled back', labelNames: ['clientName', 'readonly'], }); class DBTransaction { /** * * @param transaction */ constructor(clientName, readonly, connectionPool) { this.rolledBack = false; this.transaction = new TransactionManager_1.Transaction(); this.clientName = clientName; this.readonly = readonly; this.connectionPool = connectionPool; const labels = [clientName, readonly ? 'true' : 'false']; this.transactionExecutionDurationsHistogram = transactionExecutionDurationsHistogram.labels(...labels); this.rolledBackTransactionsCounter = rolledBackTransactionsCounter.labels(...labels); } async runQueryWithoutTransaction(sql, bindsArr) { await this.obtainConnection(); try { return await this.sanitizeAndRunQueryInConnection(sql, bindsArr); } finally { this.releaseConnection(); } } getTransaction() { return this.transaction; } async begin() { this.timer = this.transactionExecutionDurationsHistogram.startTimer(); await this.obtainConnection(); await this.doTransactionBegin(); this.transaction.begin(); this.transaction.addCommitListener(() => this.doTransactionCommit()); this.transaction.addRollbackListener(() => this.doTransactionRollback()); this.transaction.addEndListener(() => this.releaseConnection()); } async obtainConnection() { this.connection = await this.connectionPool.getConnection(); } query(sql, ...bindArrs) { return this.sanitizeAndRunQueryInConnection(sql, bindArrs); } queryAssoc(sql, bindObj) { return this.runQueryAssocPrivate(sql, bindObj); } markError(error) { this.transaction.markError(error); } sanitizeAndRunQueryInConnection(sql, bindsArr) { LOGGER.debug(`sql: ${sql} ${(bindsArr && (bindsArr.length > 0)) ? `| ${bindsArr}` : ''}`); if (!Array.isArray(bindsArr)) { bindsArr = []; } return this.runQueryInConnection(`/* Transaction Id ${this.transaction.id} */ ${sql}`, bindsArr); } runQueryAssocPrivate(sql, bindsObj) { if (sql.indexOf('::') < 0 || !bindsObj) { // tslint:disable-next-line:no-invalid-this return this.sanitizeAndRunQueryInConnection.call(this, sql, []); } sql.replace(/::(\w)+::/g, (substr, key) => { if (bindsObj.hasOwnProperty(key)) { return bindsObj[key]; } return substr; }); } doTransactionBegin() { return this.sanitizeAndRunQueryInConnection(this.getTransactionBeginSQL()); } // tslint:disable-next-line:prefer-function-over-method getTransactionBeginSQL() { return 'BEGIN'; } doTransactionCommit() { return this.sanitizeAndRunQueryInConnection(this.getTransactionCommitSQL()); } // tslint:disable-next-line:prefer-function-over-method getTransactionCommitSQL() { return 'COMMIT'; } doTransactionRollback() { this.rolledBack = true; this.rolledBackTransactionsCounter.inc(); return this.sanitizeAndRunQueryInConnection(this.getTransactionRollbackSQL()); } // tslint:disable-next-line:prefer-function-over-method getTransactionRollbackSQL() { return 'ROLLBACK'; } async releaseConnection() { if (this.connection) { this.connectionPool.release(this.connection); this.connection = null; } } async end() { try { await this.transaction.end(); } finally { if (this.timer) { this.timer(); } } } isRolledBack() { return this.rolledBack; } isReadonly() { return this.readonly; } } exports.DBTransaction = DBTransaction; //# sourceMappingURL=DBTransaction.js.map