Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Commit

Permalink
feat(transaction): add transaction support (#22)
Browse files Browse the repository at this point in the history
provide beginTransaction method to SequelizeCrudRepository with somewhat similar usage as loopback

GH-21
  • Loading branch information
shubhamp-sf authored Mar 3, 2023
1 parent d7358c2 commit 331238d
Show file tree
Hide file tree
Showing 29 changed files with 933 additions and 135 deletions.
1 change: 1 addition & 0 deletions .cz-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = {
{name: 'core'},
{name: 'repository'},
{name: 'datasource'},
{name: 'transaction'},
],

appendBranchNameToCommitMessage: true,
Expand Down
78 changes: 75 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,79 @@ An example of the filter object might look like this to fetch the books who cont
}
```

## SQL Transactions

A Sequelize repository can perform operations in a transaction using the `beginTransaction()` method.

### Isolation levels

When you call `beginTransaction()`, you can optionally specify a transaction isolation level. It support the following isolation levels:

- `Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED` (default)
- `Transaction.ISOLATION_LEVELS.READ_COMMITTED`
- `Transaction.ISOLATION_LEVELS.REPEATABLE_READ`
- `Transaction.ISOLATION_LEVELS.SERIALIZABLE`

### Options

Following are the supported options:

```ts
{
autocommit?: boolean;
isolationLevel?: Transaction.ISOLATION_LEVELS;
type?: Transaction.TYPES;
deferrable?: string | Deferrable;
/**
* Parent transaction.
*/
transaction?: Transaction | null;
}
```

### Example

```ts
// Get repository instances. In a typical application, instances are injected
// via dependency injection using `@repository` decorator.
const userRepo = await app.getRepository(UserRepository);

// Begin a new transaction.
// It's also possible to call `userRepo.dataSource.beginTransaction` instead.
const tx = await userRepo.beginTransaction({
isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE,
});

try {
// Then, we do some calls passing this transaction as an option:
const user = await userRepo.create(
{
firstName: 'Jon',
lastName: 'Doe',
},
{transaction: tx},
);

await userRepo.updateById(
user.id,
{
firstName: 'John',
},
{transaction: tx},
);

// If the execution reaches this line, no errors were thrown.
// We commit the transaction.
await tx.commit();
} catch (error) {
// If the execution reaches this line, an error was thrown.
// We rollback the transaction.
await tx.rollback();
}
```

Switching from loopback defaults to sequelize transaction is as simple as [this commit](https://github.com/shubhamp-sf/loopback4-sequelize-transaction-example/commit/321791c93ffd10c3af13e8b891396ae99b632a23) in [loopback4-sequelize-transaction-example](https://github.com/shubhamp-sf/loopback4-sequelize-transaction-example).

<!-- tutorial-end -->

## Debug strings reference
Expand Down Expand Up @@ -145,9 +218,8 @@ There are three built-in debug strings available in this extension to aid in deb

Please note, the current implementation does not support the following:

1. SQL Transactions.
2. Loopback Migrations (via default `migrate.ts`). Though you're good if using external packages like [`db-migrate`](https://www.npmjs.com/package/db-migrate).
3. Connection Pooling is not implemented yet.
1. Loopback Migrations (via default `migrate.ts`). Though you're good if using external packages like [`db-migrate`](https://www.npmjs.com/package/db-migrate).
2. Connection Pooling is not implemented yet.

Community contribution is welcome.

Expand Down
Loading

0 comments on commit 331238d

Please sign in to comment.