sequelize / sequelize-typescript

Decorators and some other features for sequelize
MIT License
2.78k stars 279 forks source link

How to enabe CLS? #58

Open SMAH1 opened 7 years ago

SMAH1 commented 7 years ago

In this link show how to enable cls for sequelize.

What are we can do it in sequelize-typescript?

RobinBuschmann commented 7 years ago

Since Sequelize of sequelize-typescript extends Sequelize of sequelize libraray, useCLS is available. But this method is not part of the typescript type definitions, so if you want to make the compiler happy, you need to access useCLS like this:

import {Sequelize} from 'sequelize-typescript';

Sequelize['useCLS'](namespace);
thormengkheang commented 6 years ago

@RobinBuschmann I can't use the way you mention. the compiler throw an error image

RobinBuschmann commented 6 years ago

This is caused by the noImplicitAny: true tsc compiler option. You can avoid this via Sequelize['useCLS' as any](namespace).

But we should add useCLS to the typings.

thormengkheang commented 6 years ago

@RobinBuschmann yeah adding it to the typing would be nice.

thormengkheang commented 6 years ago

@RobinBuschmann still the same error by using Sequelize['useCLS' as any](namespace). I tried (Sequelize as any)['useCLS'](namespace); still didn't work

image

select statement didn't execute the transaction it's executing the default. image

RobinBuschmann commented 6 years ago

@mengkheang your screens looking good to me. According to the sequelize docs it seems to be working like it should: http://docs.sequelizejs.com/manual/tutorial/transactions.html

thormengkheang commented 6 years ago

@RobinBuschmann as you can see in the sql log the select statement doesn't execute with the transaction id

RobinBuschmann commented 6 years ago

@mengkheang Sry, I didn't notice. Did you tried it with pure sequelize?

thormengkheang commented 6 years ago

@RobinBuschmann haven't tried it yet let me try it and see what happen.

thormengkheang commented 6 years ago

@RobinBuschmann it's working with pure sequelize

const cls = require('continuation-local-storage'),
    namespace = cls.createNamespace('sequelize-transaction');

const Sequelize = require('sequelize');
Sequelize.useCLS(namespace);

const sequelize = new Sequelize('test', 'root', 'password', {
    host: 'localhost',
    dialect: 'mysql'
});

const Project = sequelize.define('project', {
    title: Sequelize.STRING,
    description: Sequelize.TEXT
});

sequelize
    .authenticate()
    .then(() => {
        console.log('Connection has been established successfully.');
        sequelize.transaction(async function(t1) {
            console.log('check cls:', namespace.get('transaction') === t1); // true
            await Project.find();
        });
    })
    .catch((err) => {
        console.error('Unable to connect to the database:', err);
    });

SQL log

Executing (deafc788-28ea-4fb8-80b2-63603c818a8c): START TRANSACTION;
check cls: true
Executing (deafc788-28ea-4fb8-80b2-63603c818a8c): SELECT `id`, `title`, `description`, `createdAt`, `updatedAt` FROM `projects` AS `project` LIMIT 1;
Executing (deafc788-28ea-4fb8-80b2-63603c818a8c): COMMIT;
thormengkheang commented 6 years ago

@RobinBuschmann finally got it's working using it origin class

import * as cls from 'continuation-local-storage';
import * as SequelizeOrigin from 'sequelize';
import { Sequelize } from 'sequelize-typescript';

import { mysql as mysqlConfig } from '../config';

const namespace = cls.createNamespace('sequelize-transaction');

(SequelizeOrigin as any).useCLS(namespace);
RobinBuschmann commented 6 years ago

@mengkheang so you set useCLS on the origin sequelize class, continued using a sequelize-typescript sequelize instance and it is working now? Strange, but good to here that you got it to work. However this need to be investigated. Thanks for posting this!

thormengkheang commented 6 years ago

@RobinBuschmann yeah I set useCLS on the origin sequelize class but I use sequelize-typescript instance and it's working.

chanlito commented 6 years ago

@mengkheang what sorcery is this?

thormengkheang commented 6 years ago

@BruceHem hack

blankstar85 commented 6 years ago

I have cls working on mine, and seems to be working correctly. here:


const ns      = cls.createNamespace('sequelize-transaction');
class Database {
  private _sequelize: Sequelize;

  constructor() {
    (Sequelize as any)['useCLS'](ns);
    this._sequelize = new Sequelize({
      database: config.database,
      dialect: config.dialect,
      host: config.host,
      username: config.username,
      password: config.password,
      define: {
        freezeTableName: true,
        underscored: true,
      },
    });
    this._sequelize.addModels([
// loaded all models.
    ]);
  }
  getSequelize() {
    return this._sequelize;
  }
}
santiagodoldan commented 6 years ago

Here there's another workaround to enable CLS using sequelize-typescript

  (Sequelize as any).__proto__.useCLS(namespace)

__proto__ returns the original Sequelize class.