Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oracledb: commit was a no-op causing race conditions #3668

Merged
merged 3 commits into from Feb 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 11 additions & 14 deletions lib/dialects/oracledb/index.js
Expand Up @@ -108,9 +108,6 @@ Client_Oracledb.prototype.acquireRawConnection = function() {
}
connection.commitAsync = function() {
return new Bluebird((commitResolve, commitReject) => {
if (connection.isTransaction) {
return commitResolve();
}
this.commit(function(err) {
if (err) {
return commitReject(err);
Expand Down Expand Up @@ -293,7 +290,9 @@ Client_Oracledb.prototype._query = function(connection, obj) {
}

if (!obj.returning && outBinds.length === 0) {
await connection.commitAsync();
if (!connection.isTransaction) {
await connection.commitAsync();
}
return obj;
}
const rowIds = [];
Expand Down Expand Up @@ -335,17 +334,15 @@ Client_Oracledb.prototype._query = function(connection, obj) {
});
}
}
return connection.commitAsync().then(function() {
if (obj.returningSql) {
return connection
.executeAsync(obj.returningSql(), rowIds, { resultSet: true })
.then(function(response) {
obj.response = response.rows;
return obj;
});
}
if (connection.isTransaction) {
return obj;
});
}
await connection.commitAsync();
if (obj.returningSql) {
const response = await connection.executeAsync(obj.returningSql(), rowIds, { resultSet: true })
obj.response = response.rows;
}
return obj;
});
};

Expand Down
12 changes: 7 additions & 5 deletions lib/dialects/oracledb/transaction.js
Expand Up @@ -11,12 +11,14 @@ module.exports = class Oracle_Transaction extends Transaction {
return Bluebird.resolve();
}

commit(conn, value) {
async commit(conn, value) {
this._completed = true;
return conn
.commitAsync()
.then(() => value)
.then(this._resolver, this._rejecter);
try {
await conn.commitAsync();
this._resolver(value);
} catch (err) {
this._rejecter(err);
}
}

release(conn, value) {
Expand Down
6 changes: 1 addition & 5 deletions test/integration/builder/inserts.js
Expand Up @@ -1098,11 +1098,7 @@ module.exports = function(knex) {
});
});

describe('batchInsert (TODO: fix random oracle fail)', function() {
if (knex.client.driverName == 'oracledb') {
return;
}

describe('batchInsert', function() {
const driverName = knex.client.driverName;
const fiftyLengthString =
'rO8F8YrFS6uoivuRiVnwrO8F8YrFS6uoivuRiVnwuoivuRiVnw';
Expand Down
14 changes: 2 additions & 12 deletions test/integration/builder/transaction.js
Expand Up @@ -79,12 +79,7 @@ module.exports = function(knex) {
});
});

it('should be able to commit transactions (TODO: fix random oracle fail)', function() {
if (knex.client.driverName == 'oracledb') {
this.skip();
return;
}

it('should be able to commit transactions', function() {
let id = null;
return knex
.transaction(function(t) {
Expand Down Expand Up @@ -167,12 +162,7 @@ module.exports = function(knex) {
});
});

it('should be able to commit transactions with a resolved trx query (TODO: fix random oracle fail)', function() {
if (knex.client.driverName == 'oracledb') {
this.skip();
return;
}

it('should be able to commit transactions with a resolved trx query', function() {
let id = null;
return knex
.transaction(function(trx) {
Expand Down
13 changes: 1 addition & 12 deletions test/integration/builder/updates.js
Expand Up @@ -70,18 +70,7 @@ module.exports = function(knex) {
});
});

it('should immediately return updated value for other connections when updating row to DB returns (TODO: fix oracle fail)', function() {
if (knex.client.driverName == 'oracledb') {
// TODO: this test was added to catch strange random fails with oracle
// currently it looks like at least oracle transactions seem to return before
// they are actually committed to database...

// if those selects are changed to forUpdate() then the test seem to pass fine

this.skip();
return;
}

it('should immediately return updated value for other connections when updating row to DB returns', function() {
return knex('accounts').then((res) => {
function runTest() {
return Promise.all(
Expand Down
7 changes: 1 addition & 6 deletions test/integration/migrate/index.js
Expand Up @@ -245,12 +245,7 @@ module.exports = function(knex) {
});
});

it('should remove the record in the lock table once finished (TODO: fix random oracle fail)', function() {
if (knex.client.driverName == 'oracledb') {
this.skip();
return;
}

it('should remove the record in the lock table once finished', function() {
return knex('knex_migrations_lock')
.select('*')
.then(function(data) {
Expand Down
6 changes: 1 addition & 5 deletions test/integration/suite.js
Expand Up @@ -46,11 +46,7 @@ module.exports = function(knex) {
});

describe('knex.initialize', function() {
it('should allow initialize the pool with knex.initialize (TODO: fix oracle)', function() {
if (knex.client.driverName === 'oracledb') {
this.skip();
return;
}
it('should allow initialize the pool with knex.initialize', function() {
expect(knex.client.pool).to.equal(undefined);
knex.initialize();
expect(knex.client.pool.destroyed).to.equal(false);
Expand Down