Search code examples
mysqltransactionsdeadlockknex.js

Are all knex queries run in a transaction by default?


I'm not using knex.transaction, knex.forUpdate, knex.forShare, knex.batchInsert or any method that explicitly creates a transaction, yet I'm having a DEADLOCK error in my code. If knex.js does not create transactions by default, why does it create locks?

UPDATE

When those queries are executed twice very rapidly, I get a DEADLOCK exception.

let subquery2 = knex.select('pv2.*').from('projects_versions as pv2').innerJoin('versions_history as vh', 'pv2.version_id', 'vh.version_id').orderBy('vh.id', 'desc');
let subquery = knex.select('x.version_id').from(subquery2.as('x')).whereRaw('x.project_id = pv.project_id').limit(1);

let result = (await knex.raw('DELETE pv FROM projects_versions AS pv WHERE pv.version_id = ? AND NOT version_id = ?', [versionToDiscard, subquery]))[0];

if (!result.affectedRows) {
    await knex('projects_versions').update({ version_id: fifthVersion }).where('version_id', versionToDiscard);
}

Solution

  • Knex creates implicit transaction by default when runnin migrations. Otherwise knex doesn't create any implicit locks.

    There is just too little information in the question to be able to answer anything more useful to this.