0.1.2 ā€¢ Published 8 months ago

sequelize-transactional v0.1.2

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

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

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:

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:

@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:

@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:

const sequelize = new Sequelize({ ... })

initSequelizeTransactional(sequelize) // pass your Sequelize conection here

Step 3

Use Transactional annotation on your class methods.

Example:

@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:

{
  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.