I’m building integration tests for my repository layer, but I’m facing a deadlock issue because of the run of parallel tests, i used transactions to try to solve this problem but I’m still getting deadlocks here is an example of my tests:
import db from '../../../../db/db';
import EntityFactory from '../../../common/__tests__/entityFactory';
import { workspaceRepository } from '../workspaceRepository';
describe.skip('workspaceRepository', () => {
let trx: any;
beforeAll(async () => {
trx = await db.transaction();
await trx.schema.alterTable('workspaces', (table: any) => {
table.dropForeign('ownerId');
});
await Promise.all([
EntityFactory.createWorkspace(trx, 1, 1, 'workspace1', 'description', 'url'),
]);
});
test('createWorkspace', async () => {
const workspace = await workspaceRepository.createWorkspace(trx, {
ownerId: 3,
name: 'workspace5',
description: 'description',
avatarUrl: 'url',
});
expect(workspace.id).not.toBeNull();
const workspaces = await trx.select('*').from('workspaces');
expect(workspaces).toHaveLength(2);
await EntityFactory.deleteWorkspaces(trx, [workspace.id]);
});
test('getAllUserWorkspaces', async () => {
const workspaces = await workspaceRepository.findAllUserWorkspaces(trx, 1);
expect(workspaces).toHaveLength(1);
});
// more tests.
afterAll(async () => {
await Promise.all([EntityFactory.deleteWorkspaces(trx, [1])]);
await trx.schema.alterTable('workspaces', (table: any) => {
table.foreign('ownerId').references('id').inTable('users');
});
trx.commit();
});
}, 15000);
here is the content of my repository:
import { CreateWorkspaceDto, Workspace } from '@/api/workspace/workspaceModel';
export const workspaceRepository = {
createWorkspace: async (trx: any, workspace: CreateWorkspaceDto): Promise<Workspace> => {
const ids = await trx('workspaces').insert(workspace);
const newWorkspace = await trx('workspaces').where('id', ids[0]).first();
return newWorkspace;
},
findAllUserWorkspaces: async (trx: any, userId: number): Promise<Workspace[]> => {
return await trx.select('*').from('workspaces').where('ownerId', userId);
},
findById: async (trx: any, id: number): Promise<Workspace | null> => {
return await trx.select('*').from('workspaces').where('id', id).first();
},
deleteWorkspace: async (trx: any, id: number): Promise<void> => {
await trx('workspaces').where('id', id).delete();
},
};
error:
FAIL src/api/coworkers/__tests__/04_coworkersRepository.test.ts > coworkerRepository
Error: alter table `coworkers` drop foreign key `coworkers_userid_foreign` - Deadlock found when trying to get lock; try restarting transaction
❯ Packet.asError node_modules/mysql2/lib/packets/packet.js:728:17
.
.
.
Serialized Error: { code: 'ER_LOCK_DEADLOCK', errno: 1213, sqlState: '40001', sqlMessage: 'Deadlock found when trying to get lock; try restarting transaction', sql: 'alter table `coworkers` drop foreign key `coworkers_userid_foreign`' }
--------------------------------------------------------
FAIL src/api/coworkers/__tests__/04_coworkersRepository.test.ts > coworkerRepository
Error: alter table `coworkers` add constraint `coworkers_userid_foreign` foreign key (`userId`) references `users` (`id`) - Duplicate foreign key constraint name 'coworkers_userid_foreign'
❯ Packet.asError node_modules/mysql2/lib/packets/packet.js:728:17
.
.
Serialized Error: { code: 'ER_FK_DUP_NAME', errno: 1826, sqlState: 'HY000', sqlMessage: 'Duplicate foreign key constraint name 'coworkers_userid_foreign'', sql: 'alter table `coworkers` add constraint `coworkers_userid_foreign` foreign key (`userId`) references `users` (`id`)' }
what am i missing here, is there is a way to it better?