Skip to content

Commit

Permalink
fix: fix sequelize transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
s4nt14go committed Mar 7, 2024
1 parent d95f922 commit cf8d3dd
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 16 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,5 @@ Install and run tests:
npm ci
npm test
```

> It may take a few minutes to run all unit tests. For new projects, I recommend using `vitest`, which is much faster.
23 changes: 13 additions & 10 deletions src/modules/accounts/repos/AccountRepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import { Repository } from '../../../shared/core/Repository';
import { IAccountRepo, TransferProps } from './IAccountRepo';

export class AccountRepo extends Repository<Account> implements IAccountRepo {
// Read comment in src/shared/core/Repository.ts about the use of this.transaction
private Account: any; // eslint-disable-line @typescript-eslint/no-explicit-any
private Transaction: any; // eslint-disable-line @typescript-eslint/no-explicit-any

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public constructor(models: any) {
super();
// Put this.transaction in all repos queries: this.<Model>.<find/create/destroy/etc>({...}, { transaction: this.transaction })
// this.transaction type is SequelizeTransaction and is populated when Transaction decorator is used, if that decorator isn't used, this.transaction is null and doesn't have any effect (SQL transaction isn't' used)
this.Account = models.Account;
this.Transaction = models.Transaction;
}
Expand All @@ -40,8 +39,8 @@ export class AccountRepo extends Repository<Account> implements IAccountRepo {
const rawAccount = await this.Account.findOne(
{
where: { userId },
transaction: this.transaction,
},
{ transaction: this.transaction }
);
if (!rawAccount) return null;
const transactions = await this.getTransactions(
Expand All @@ -62,7 +61,7 @@ export class AccountRepo extends Repository<Account> implements IAccountRepo {
...raw,
accountId,
},
{ transaction: this.transaction }
{ transaction: this.transaction },
);
}

Expand All @@ -81,7 +80,7 @@ export class AccountRepo extends Repository<Account> implements IAccountRepo {
...rawAccount,
userId,
},
{ transaction: this.transaction }
{ transaction: this.transaction },
);
const initialTransaction = newAccount.transactions[0];
const rawTransaction = TransactionMap.toPersistence(initialTransaction);
Expand All @@ -90,7 +89,7 @@ export class AccountRepo extends Repository<Account> implements IAccountRepo {
...rawTransaction,
accountId: newAccount.id.toString(),
},
{ transaction: this.transaction }
{ transaction: this.transaction },
);
return newAccount;
}
Expand All @@ -101,12 +100,16 @@ export class AccountRepo extends Repository<Account> implements IAccountRepo {
if (!account)
return console.log(`No account for userId ${userId}, so nothing is deleted`);
await this.Transaction.destroy(
{ where: { accountId: account.id.toString() } },
{ transaction: this.transaction }
{
where: { accountId: account.id.toString() },
transaction: this.transaction,
},
);
await this.Account.destroy(
{ where: { userId } },
{ transaction: this.transaction }
{
where: { userId },
transaction: this.transaction,
},
);
}
}
11 changes: 5 additions & 6 deletions src/modules/users/repos/UserRepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import { Repository } from '../../../shared/core/Repository';
import { EntityID } from '../../../shared/domain/EntityID';

export class UserRepo extends Repository<User> implements IUserRepo {
// Read comment in src/shared/core/Repository.ts about the use of this.transaction
private User: any; // eslint-disable-line @typescript-eslint/no-explicit-any

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public constructor(models: any) {
super();
// Put this.transaction in all repos queries: this.<Model>.<find/create/destroy/etc>({...}, { transaction: this.transaction })
// this.transaction type is SequelizeTransaction and is populated when Transaction decorator is used, if that decorator isn't used, this.transaction is null and doesn't have any effect (SQL transaction isn't' used)
this.User = models.User;
}

Expand All @@ -22,8 +21,8 @@ export class UserRepo extends Repository<User> implements IUserRepo {
where: {
username,
},
transaction: this.transaction,
},
{ transaction: this.transaction }
);
if (user) return UserMap.toDomain(user.get());
return null;
Expand All @@ -36,8 +35,8 @@ export class UserRepo extends Repository<User> implements IUserRepo {
where: {
email,
},
transaction: this.transaction,
},
{ transaction: this.transaction }
);
if (user) return UserMap.toDomain(user.get());
return null;
Expand All @@ -50,8 +49,8 @@ export class UserRepo extends Repository<User> implements IUserRepo {
where: {
email,
},
transaction: this.transaction,
},
{ transaction: this.transaction }
);
return !!user;
}
Expand All @@ -68,8 +67,8 @@ export class UserRepo extends Repository<User> implements IUserRepo {
where: {
id,
},
transaction: this.transaction,
},
{ transaction: this.transaction }
);
}
}
5 changes: 5 additions & 0 deletions src/shared/core/Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { Transaction } from 'sequelize';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export abstract class Repository<T extends AggregateRoot<unknown>> {
// Put this.transaction in all repos queries, e.g.:
// this.<Model>.create({...}, { transaction: this.transaction })
// this.<Model>.findAll/findOne/destroy({ where: ..., transaction: this.transaction })
// this.<Model>.findByPk(pk, { transaction: this.transaction })
// this.transaction is SequelizeTransaction and is populated when Transaction decorator is used, if that decorator isn't used, this.transaction is null and doesn't have any effect (SQL transaction isn't used)
protected transaction?: Transaction;
public setTransaction(transaction: Transaction) {
this.transaction = transaction;
Expand Down

0 comments on commit cf8d3dd

Please sign in to comment.