Open
Description
Issue
Configuration for CLS (Continuation-Local Storage) seems not to work or I'm doing something wrong.
CRUD operations don't join existing transaction.
Any chance to get it done right?
Versions
- nestjs: 8.0.6
- cls-hooked: "4.2.2"
- sequelize: 6.6.5
- sequelize-typescript: 2.1.0
- typescript: 4.4.2
Issue type
- bug report
- feature request
- not sure. problem maybe in front of monitor. :-)
Actual behavior
CRUD operations not joining current transaction.
Expected behavior
Opposite :)
Steps to reproduce
Configuration (Somewhere on application init, before module initialization)
import { Sequelize } from 'sequelize-typescript';
import * as cls from 'cls-hooked';
const ns = cls.createNamespace('sequelize-ns');
Sequelize.useCLS(ns);
Interceptor
import { Sequelize } from 'sequelize-typescript';
@Injectable()
export class TransactionInterceptor implements NestInterceptor {
constructor(private readonly sequelize: Sequelize) {}
async intercept(
context: ExecutionContext,
next: CallHandler,
): Promise<Observable<any>> {
// Managed tx with autocommit and rollbacks on error
return await this.sequelize.transaction(async (tx: Transaction) => {
GqlExecutionContext.create(context).getContext().transaction = tx;
return next.handle();
});
}
}
Not working version
class FooResolver {
...
@UseInterceptors(TransactionInterceptor)
@Mutation(() => FooModel)
async createFoo(
@Args('dto') dto: FooInput,
): Promise<FooModel> {
const foo = new FooEntity(dto);
await foo.save();
const foo2 = new FooEntity({ id: 1, name: null });
await foo2.save(); // This one will fail
return new FooModel(foo2);
}
}
Executing (b32b84c4-d552-4073-a2fa-d4a35af26d3f): START TRANSACTION;
Executing (b32b84c4-d552-4073-a2fa-d4a35af26d3f): SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Executing (default): INSERT INTO "tbl_foo" ("id","name") VALUES ($1,$2) RETURNING "id","name"; !!! Not in transaction
Executing (default): INSERT INTO "tbl_foo" ("id","name") VALUES ($1,$2) RETURNING "id","name"; !!! Not in transaction
Executing (b32b84c4-d552-4073-a2fa-d4a35af26d3f): ROLLBACK;
[Nest] 28804 - 02.09.2021, 10:42:03 ERROR [ExceptionsHandler] Validation error
...
Working version (the uggly one, passing transaction to each statement)
class FooResolver {
...
@UseInterceptors(TransactionInterceptor)
@Mutation(() => FooModel)
async createFoo2(
@Context ctx: { transaction: Transaction }, <-- Tx from context
@Args('dto') dto: FooInput,
): Promise<FooModel> {
const foo = new FooEntity(dto);
await foo.save({ transaction: ctx.transaction });
const foo2 = new FooEntity({ id: 1, name: null });
await foo2.save({ transaction: ctx.transaction }); // This one will fail
return new FooModel(foo2);
}
Executing (977845cd-25ea-4350-997b-fb20b6d59030): START TRANSACTION;
Executing (977845cd-25ea-4350-997b-fb20b6d59030): SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Executing (977845cd-25ea-4350-997b-fb20b6d59030): INSERT INTO "tbl_foo" ("id","name") VALUES ($1,$2) RETURNING "id","name";
Executing (977845cd-25ea-4350-997b-fb20b6d59030): INSERT INTO "tbl_foo" ("id","name") VALUES ($1,$2) RETURNING "id","name";
Executing (977845cd-25ea-4350-997b-fb20b6d59030): ROLLBACK;
[Nest] 77072 - 02.09.2021, 11:03:03 ERROR [ExceptionsHandler] Validation error
...
Metadata
Metadata
Assignees
Labels
No labels