odavid / typeorm-transactional-cls-hooked

A Transactional Method Decorator for typeorm that uses cls-hooked to handle and propagate transactions between different repositories and service methods. Inpired by Spring Trasnactional Annotation and Sequelize CLS
MIT License
524 stars 87 forks source link

Transaction doesn't work #95

Open naorye opened 3 years ago

naorye commented 3 years ago

I am using nestjs with typeorm and recentrly I added transaction support with typeorm-transactional-cls-hooked. I made the following method:

@Injectable()
class ConnectionService {
  constructor(
    @InjectRepository(Connection)
    private connectionsRepository: ConnectionsRepository,
  ) {}

  @Transactional()
  public async updateConnection(userId: string, connectionId: string) {
    const connection = await this.getConnectionById(userId, connectionId);

    connection.name = '111';
    await this.connectionsRepository.save(connection);

    throw new Error('error test');

    connection.name = '222';
    await this.connectionsRepository.save(connection);
  }
}

connectionsRepository is defined like that:

import { EntityRepository } from 'typeorm';
import { BaseRepository } from 'typeorm-transactional-cls-hooked';
import { Connection } from '../entities/connection.entity';

@EntityRepository(Connection)
export class ConnectionsRepository extends BaseRepository<Connection> {}

When I am calling updateConnection, I end up with connection.name equals to 111 even though the transaction was rejected. What I am missing?

johntranz commented 2 years ago

me too 👍

maborroto commented 2 years ago

@naorye @Jane-Tran Hello all, I solved the problem by writing the proper setting for the Nestjs TypeOrmModule when using Custom Repositories, please see the line of imports in the code below:

@Module({
  providers: [UsersService],
  imports: [TypeOrmModule.forFeature([UsersRepository])],
  exports: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}

The "Custom Repository" must be provided to when calling .forFeature()

Hope this helps!!!

HappyHappy1996 commented 2 years ago

Hi all, I had the same problem and it turned out I was missing one thing, so this is an example of a service I had before adding typeorm-transactional-cls-hooked:

@Injectable()
export class MyEntityService {
  constructor(
    @InjectRepository(MyEntity)
    private readonly repository: Repository<MyEntity>,
  ) {}

  ...

  }

So after adding typeorm-transactional-cls-hooked it got changed to

@Injectable()
export class MyEntityService {
  constructor(
    @InjectRepository(MyEntity)
    private readonly repository: MyEntityRepository, // <--------------------------------- CHANGED HERE
  ) {}

  ...

  }

But what I missed was that I forgot to delete @InjectRepository(MyEntity), so the final working code looks like this:

@Injectable()
export class MyEntityService {
  constructor(
    // <--------------------------------- CHANGED HERE
    private readonly repository: MyEntityRepository,
  ) {}

  ...

  }