mirror of
https://github.com/knex/knex.git
synced 2025-07-07 09:01:19 +00:00
99 lines
2.9 KiB
JavaScript
99 lines
2.9 KiB
JavaScript
const Transaction = require('../../execution/transaction');
|
|
const { timeout, KnexTimeoutError } = require('../../util/timeout');
|
|
const debugTx = require('debug')('knex:tx');
|
|
|
|
// There's also a "read only", but that's not really an "isolationLevel"
|
|
const supportedIsolationLevels = ['read committed', 'serializable'];
|
|
// Remove this if you make it work and set it to true
|
|
const isIsolationLevelEnabled = false;
|
|
|
|
module.exports = class Oracle_Transaction extends Transaction {
|
|
// disable autocommit to allow correct behavior (default is true)
|
|
begin(conn) {
|
|
if (this.isolationLevel) {
|
|
if (isIsolationLevelEnabled) {
|
|
if (!supportedIsolationLevels.includes(this.isolationLevel)) {
|
|
this.client.logger.warn(
|
|
'Oracle only supports read committed and serializable transactions, ignoring the isolation level param'
|
|
);
|
|
} else {
|
|
// I tried this, but it didn't work
|
|
// Doc here: https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SET-TRANSACTION.html
|
|
return this.query(conn, `SET TRANSACTION ${this.isolationLevel}`);
|
|
}
|
|
} else {
|
|
this.client.logger.warn(
|
|
'Transaction isolation is not currently supported for Oracle'
|
|
);
|
|
}
|
|
}
|
|
return Promise.resolve();
|
|
}
|
|
|
|
async commit(conn, value) {
|
|
this._completed = true;
|
|
try {
|
|
await conn.commitAsync();
|
|
this._resolver(value);
|
|
} catch (err) {
|
|
this._rejecter(err);
|
|
}
|
|
}
|
|
|
|
release(conn, value) {
|
|
return this._resolver(value);
|
|
}
|
|
|
|
rollback(conn, err) {
|
|
this._completed = true;
|
|
debugTx('%s: rolling back', this.txid);
|
|
return timeout(conn.rollbackAsync(), 5000)
|
|
.catch((e) => {
|
|
if (!(e instanceof KnexTimeoutError)) {
|
|
return Promise.reject(e);
|
|
}
|
|
this._rejecter(e);
|
|
})
|
|
.then(() => {
|
|
if (err === undefined) {
|
|
if (this.doNotRejectOnRollback) {
|
|
this._resolver();
|
|
return;
|
|
}
|
|
err = new Error(`Transaction rejected with non-error: ${err}`);
|
|
}
|
|
this._rejecter(err);
|
|
});
|
|
}
|
|
|
|
savepoint(conn) {
|
|
return this.query(conn, `SAVEPOINT ${this.txid}`);
|
|
}
|
|
|
|
async acquireConnection(config, cb) {
|
|
const configConnection = config && config.connection;
|
|
|
|
const connection =
|
|
configConnection || (await this.client.acquireConnection());
|
|
try {
|
|
connection.__knexTxId = this.txid;
|
|
connection.isTransaction = true;
|
|
return await cb(connection);
|
|
} finally {
|
|
debugTx('%s: releasing connection', this.txid);
|
|
connection.isTransaction = false;
|
|
try {
|
|
await connection.commitAsync();
|
|
} catch (err) {
|
|
this._rejecter(err);
|
|
} finally {
|
|
if (!configConnection) {
|
|
await this.client.releaseConnection(connection);
|
|
} else {
|
|
debugTx('%s: not releasing external connection', this.txid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|