UNPKG

sequelize-transactional

Version:
126 lines (95 loc) • 3.38 kB
# sequelize-transactional A `Transactional` method decorator for sequelize that uses cls-hooked to handle and propagate transactions between different service methods. āœ… This package is very suitable for use with NestJS. ## Installation ```shell yarn add sequelize-transactional # or npm install sequelize-transactional --save ``` ## Usage ### _Step 1_ **Before establishing any connections** using Sequelize, you need to enable Sequelize to use node CLS: ```typescript import { initSequelizeCLS } from 'sequelize-transactional'; initSequelizeCLS(); ``` In NesJS you can call this in the main.ts after the app declaration. ### _Step 2_ ### If you use sequelize in your NestJS app: Import `SequelizeTransactionalModule.register()` into your root application module. Example: ```typescript @Module({ imports: [ SequelizeModule.forRoot({ ... }), SequelizeTransactionalModule.register(), ], controllers: [AppController], providers: [AppService], }) export class AppModule {} ``` If you specified custom connection name in `SequelizeModule`, pass `connectionName` into options: ```typescript @Module({ imports: [ SequelizeModule.forRoot({ ... name: 'my-connection-name', }), SequelizeTransactionalModule.register({ connectionName: 'my-connection-name' }), ], controllers: [AppController], providers: [AppService], }) export class AppModule {} ``` ### If you don't use NestJS Just call _initSequelizeTransactional_ after establishing a connection: ```typescript const sequelize = new Sequelize({ ... }) initSequelizeTransactional(sequelize) // pass your Sequelize conection here ``` ### Step 3 Use `Transactional` annotation on your class methods. Example: ```typescript @Injectable() export class AppService { constructor( @InjectModel(Something) private readonly something: typeof Something, private readonly anotherService: AnotherService, ) {} @Transactional() async appMethod(): Promise<void> { await this.something.create({ message: 'hello' }); await this.something.create({ message: 'world' }); await this.anotherService.method(); // other service's method will use the same transaction } } ``` `@Transactional` decorator accepts `options` object: ```typescript { isolationLevel?: string; // Isolation Level of transaction. Default value depends on your Sequelize config or the database you use propagation?: string; // Default value is REQUIRED. Allowed options are described below } ``` ## Propagation options - `REQUIRED` (default) - If exists, use current transaction, otherwise create a new one. - `SUPPORTS` - If exists, use current transaction, otherwise execute without transaction. - `MANDATORY` - If exists, use current transaction, otherwise throw an exception. - `NEVER` - Execute without transaction. If an active transaction exists, throw an exception. - `NOT_SUPPORTED` - Execute without transaction, suspend an active transaction if it exists. - `REQUIRES_NEW` - Always execute in a separate transaction, suspend an active transaction if it exists. ## Isolation Level Options - `READ UNCOMMITTED` - `READ COMMITTED` - `REPEATABLE READ` - `SERIALIZABLE` For more info refer to your database documentation.